在寻找二叉树实现的示例时,我注意到提供的代码中有些奇怪的地方 here .在 Node 结构的构造函数中,一个非指针类型变量被分配给一个指针类型。
它编译得很好(我使用的是 GCC 5.3.0)。让我真正困惑的是编译依赖于其他构造函数的参数,val。
它对类方法没有影响,只对构造函数有影响:
template <typename T>
class Test {
Test* testPtr;
void testMethod(T t, Test<T> notAPointer) { // OK
this->testPtr = notAPointer;
}
void testMethod(Test<T> notAPointer) { // OK
this->testPtr = notAPointer;
}
Test(T t, Test<T> notAPointer) { // OK
this->testPtr = notAPointer;
}
Test(Test<T> notAPointer) { // compilation error
this->testPtr = notAPointer;
}
};
我得到的编译错误是:
invalid constructor; you probably meant ‘Test (const Test&)’
为什么会这样?标准中哪里描述了这种行为?
最佳答案
你的最后一个构造函数是 copy constructor .禁止使用按值传递其参数的复制构造函数,否则最终会导致无限递归。
你得到的错误类似于
struct Foo
{
Foo(Foo);
};
更准确地说,根据标准:
12.8/2 复制和移动类对象[class.copy]
A non-template constructor for class
X
is a copy constructor if its first parameter is of typeX&
,const X&
,volatile X&
orconst volatile X&
, and either there are no other parameters or else all other parameters have default arguments (8.3.6). [ Example:X::X(const X&)
andX::X(X&,int=1)
are copy constructors.
其他构造函数/成员函数看起来没问题,因为它们没有被实例化,并且代码在语法上是正确的(理论上,Test<T>
可能有一个到 T*
的转换运算符用于某些特殊化,并且编译器之前无法检查实例化)。然而,复制构造函数必须具有明确的形式,这是由编译器强制执行的。
关于C++,将非指针类型分配给模板类的成员指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35382083/