让我用一个简单的例子来证明:
class A
{
public:
A() { cout << "A::A()" << endl; }
A(A const& a) : _a(a._a) { cout << "A::(A Copy Const)" << endl; }
A(A& a) : _a(a._a) { cout << "A::(A Copy)" << endl; }
template <typename _T1>
A(_T1& v1) : _a(v1) { cout << "A::(T conversion)" << endl; }
~A() { cout << "A::~A()" << endl; }
void say() { cout << "A::say()" << endl; }
private:
int _a;
};
int main(int argc, char* argv[])
{
A a1(A(argc)); // Line 1: ERM?
a1.say();
return 0;
}
一些事情:
定义复制构造函数的const和非const版本有什么危害吗?我这样做的原因是,这显然有助于编译器区分模板化的构造函数,即
A const a1(argc);
A a2(a1); // <-- correctly call the const copy ctor
A a3(argc);
A a4(a3); // <-- correctly call the non-const copy ctor
有没有更好的方法来确保在上面的示例中,始终通过模板化构造函数调用复制构造函数?
其次,从纯编码的角度来看,第1行似乎没问题,目的是创建一个带A
的临时argc
,然后触发复制构造函数,但是我得到以下异常(gcc 4.4.4):
错误:请求'a1'中的成员'说',这是非类型'A(A)'
我相信这里发生的事情是编译器认为a1
是函数定义,这是正确的吗?如果是这样,编写特定代码行的正确方法是什么?以下似乎是一个黑客!
A a1(true ? A(argc) : A());
P.S。请忽略所有风格的foobars,为什么我想要这样做......! :)
答案 0 :(得分:2)
模板化构造函数永远不是(正式)复制构造函数。
你是对的,可以作为函数声明的声明被视为函数声明。它被称为C ++中“最令人烦恼的解析”。一种解决方法是使用额外括号,例如T v(( U ))
。
添加auto
关键字可能会修复它,我还没试过。但是,由于auto
在C ++ 0x中获得了新的含义,即使它在C ++ 98中适用于该问题,也不习惯使用它。
干杯&amp;第h