Reputation: 316
I have a template class called Variable
, with a specialized constructor for char*, which is defined as follows:
template<>
Variable<char*>::Variable(char * const &arg_value)
{
value = new char[strlen(arg_value) + 1];
strncpy(value, arg_value, strlen(arg_value));
value[strlen(arg_value)] = '\0';
}
Now, I have this statement, that declares a Variable<char*>
:
Variable<char*> stringVar = const_cast<char*>("Hi");
In my Variable
definition, I never declared or defined a copy constructor to a const char*. However, the statement works perfectly fine. Why is this? I am quite positive that stringVar
has a data-type of Variable<char*>
, but this still works. Where is this assignment coming from?
Upvotes: 0
Views: 129
Reputation: 208323
char hi[] = "Hi";
Variable<char*> stringVar = hi;
The second line above is semantically equivalent to:
Variable<char*> stringVar( implicit_cast<Variable<char*>>(hi) );
Assuming that there was such a thing as implicit_cast
that performed a type conversion to the destination type if and only if there is an implicit conversion available. In your case, the constructor:
Variable<T>::Variable( T const & )
provides for the implicit conversion: Variable<char*>::Variable( char * const & )
can be used to convert from char*
to Variable<char*>
.
Note that while semantically this is what happens, in reality the copy will be elided and the code will be compiled to the equivalent:
Variable<char*> stringVar(hi);
That is, after all checks have been performed: an implicit conversion from hi
to the type is available, and the copy constructor can be called implicitly.
Upvotes: 1
Reputation: 476970
A constructor that takes one argument allows for implicit conversions. Here's a simpler example of your situation:
struct Foo { Foo(int, double = 0.5, char = 'a') { } };
void bar(Foo);
Foo x = 1; // OK!
bar(2); // also OK
To inhibit this implicit conversion, say explicit
:
struct Eew { explicit Eew(int) { } };
// Eew e = 3; // error
Eew e2 = Eew(3); // OK but weird
Eew e3(3); // correct
Upvotes: 4
Reputation: 66194
You're invoking the default copy constructor. Declare one hidden in your Variable<> template and watch the compile break.
Upvotes: 1
Reputation: 55887
Variable<char*> stringVar = const_cast<char*>("Hi");
call implicit c-tor of class Variable<char*>
.
It's equal to
Variable<char*> stringVar = Variable<char*>(const_cast<char*>("Hi"));
Upvotes: 2