我有一个名为Variable
的模板类,带有char *的专用构造函数,定义如下:
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';
}
现在,我有这个声明,宣布Variable<char*>
:
Variable<char*> stringVar = const_cast<char*>("Hi");
在我的Variable
定义中,我从未向const char *声明或定义了复制构造函数。但是,该声明完全正常。为什么是这样?我非常肯定stringVar
的数据类型为Variable<char*>
,但这仍然有效。这项任务来自哪里?
答案 0 :(得分:4)
采用一个参数的构造函数允许隐式转换。以下是您的情况的简单示例:
struct Foo { Foo(int, double = 0.5, char = 'a') { } };
void bar(Foo);
Foo x = 1; // OK!
bar(2); // also OK
要禁止此隐式转化,请说explicit
:
struct Eew { explicit Eew(int) { } };
// Eew e = 3; // error
Eew e2 = Eew(3); // OK but weird
Eew e3(3); // correct
答案 1 :(得分:2)
Variable<char*> stringVar = const_cast<char*>("Hi");
调用类Variable<char*>
的隐式c-tor。
它等于
Variable<char*> stringVar = Variable<char*>(const_cast<char*>("Hi"));
答案 2 :(得分:1)
您正在调用默认的复制构造函数。声明隐藏在您的变量&lt;&gt;中的一个模板并观察编译中断。
答案 3 :(得分:1)
char hi[] = "Hi";
Variable<char*> stringVar = hi;
上面的第二行语义等同于:
Variable<char*> stringVar( implicit_cast<Variable<char*>>(hi) );
当且仅当存在可用的隐式转换时,假设有implicit_cast
这样的事情执行到目标类型的类型转换。在您的情况下,构造函数:
Variable<T>::Variable( T const & )
提供了隐式转换:Variable<char*>::Variable( char * const & )
可用于将char*
转换为Variable<char*>
。
请注意,虽然语义上发生了这种情况,但实际上副本将被删除,代码将被编译为等效代码:
Variable<char*> stringVar(hi);
也就是说,在执行了所有检查之后:从hi
到类型的隐式转换是可用的,并且可以隐式调用复制构造函数。