Reputation: 113
i have a question about explicit and templates:
template<class T>
class A {
class A_Impl {
T var;
public:
explicit A_Impl(T var1) : var(var1), version(1)
{
}
A_Impl(const A_Impl& a ) : var(a.var), version(1)
{
}
const A_Impl& operator=(const A_Impl& a)
{
var=a.var;++version;return *this;
}
operator T() const { return var; }
friend class A<T>;
};
A_Impl a;
public:
A(T var): a(var)
{
}
A_Impl& get() { return a; }
};
void main() {
A<int> a1(5);
cout<<"a1 = "<<a1.get()<<endl;
a1.get()=7;
cout<<"a1 = "<<a1.get()<<endl;
a1=13;
cout<<"a1 = "<<a1.get()<<endl;
}
I get en error at a1.get()=7;
which says no operator "=" matches these operands
Also, if i take explicit word out it will compile, but i dont understand the difference between the a1.get()
function and a1=13;
which works fine even with explicit.
Upvotes: 0
Views: 95
Reputation: 76280
I get en error at a1.get()=7; which says no operator "=" matches these operands
There's no way to convert 7
to a A_Impl
for operator=
, because the constructor A_Impl(T)
, which in this instance is expanded to A_Impl(int)
, is declared explicit
.
You can either remove the explicit
keyword, or explicitly create an A_Impl
with:
a1.get() = A_Impl(7);
Alternatively you can also declare a specific operator=
:
const A_Impl& operator=(const T&)
for the A_Impl
class.
Also, if i take explicit word out it will compile, but i dont understand the difference between the a1.get() function and a1=13; which works fine even with explicit.
a1 = 13
works fine because the template class A
has a non-explicit constructor to T
(specifically A(T var)
), which, in this case, match perfect for T = int
.
Also notice that main
should always return int
, not void
.
Upvotes: 1
Reputation: 11502
You only have declared a copy assignment operator: const A_Impl& operator=(const A_Impl& a)
,
but not a assignment operator for T
types: const A_Impl& operator=(const T& a)
.
If you dont have an explicit
constructor, your int (7
) will implecitely converted to a A_Impl
object which is then assigned to your returned reference.
If your constructor is explicit
this implecit conversion is not possible anymore (thats what explicit
actually does), and thus there is no possibility to assign an int
to a A_Impl
.
What however would work if your A_Impl
class is public, is this (the same that happens under the hood if you dont write explicit
):
a1.get() = A_Impl(7);
Upvotes: 0