ZERO
ZERO

Reputation: 316

Template's data-type

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

Answers (4)

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

Kerrek SB
Kerrek SB

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

WhozCraig
WhozCraig

Reputation: 66194

You're invoking the default copy constructor. Declare one hidden in your Variable<> template and watch the compile break.

Upvotes: 1

ForEveR
ForEveR

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

Related Questions