复制/转换构造函数定义(const / non-const)

时间:2010-11-09 17:45:05

标签: c++

让我用一个简单的例子来证明:

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,为什么我想要这样做......! :)

1 个答案:

答案 0 :(得分:2)

模板化构造函数永远不是(正式)复制构造函数。

你是对的,可以作为函数声明的声明被视为函数声明。它被称为C ++中“最令人烦恼的解析”。一种解决方法是使用额外括号,例如T v(( U ))

添加auto关键字可能会修复它,我还没试过。但是,由于auto在C ++ 0x中获得了新的含义,即使它在C ++ 98中适用于该问题,也不习惯使用它。

干杯&amp;第h