我有以下小代码:
template <typename T>
class V
{
public:
T x;
explicit V(T & _x)
:x(_x){}
};
int main()
{
V<float> b(1.0f); // fails
return 0;
}
它碰巧失败了。 g ++ 4.4.5返回的消息是:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
../main.cpp: In function ‘int main()’:
../main.cpp:19: error: no matching function for call to ‘V<float>::V(float)’
../main.cpp:10: note: candidates are: V<T>::V(T&) [with T = float]
../main.cpp:6: note: V<float>::V(const V<float>&)
事情是......第二个构造函数来了吗?我真的不知道......
答案 0 :(得分:6)
其他答案讨论了为什么你会遇到编译时失败(大多数问题都是关于这些失败是问题最突出的部分)。然而。关于你的明确问题,“第二个构造函数是从哪里来的?”:
12.8 / 4标准的“复制类对象”说:
如果类定义没有显式声明复制构造函数,则会隐式声明一个。
如果您想避免使用隐式副本,可以使用一些“不可复制”的习语(例如boost::noncopyable
):http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin
答案 1 :(得分:4)
编译器为您的类提供了一个复制构造函数和赋值运算符。它试图将该复制构造函数与main
中的语句进行匹配。此代码的问题在于,在类V
的构造函数中,您将参数作为非const引用。执行V<float> b(1.0f)
时,编译器将为值float
创建类型为1.0f
的未命名临时变量。但是,这个未命名的临时不能绑定到非const引用,它只能绑定到const引用。因此,您需要将构造函数签名更改为explicit V(const T & _x)
。