无法理解复制构造函数的来源

时间:2010-10-08 04:43:05

标签: c++ templates constructor

我有以下小代码:

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>&)

事情是......第二个构造函数来了吗?我真的不知道......

2 个答案:

答案 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)