开发者

copy/conversion constructor definitions (const/non-const)

开发者 https://www.devze.com 2023-01-24 01:03 出处:网络
Let me demonstrate with a simple example: class A { public: A() { cout << \"A::A()\" << endl; }

Let me demonstrate with a simple example:

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;
}

Couple of things:

Is there any harm in defining a const and non-const version of the copy constructor? Reason I've done this is that this apparently helps the compiler differentiate from the templated co开发者_StackOverflow社区nstructor, i.e.

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

Is there a better way to ensure that in the above example, the copy constructor is always called over the templated constructor?

Secondly, from a pure coding perspective, Line 1 appears to be okay, the intention is to create a temporary A with argc, and then trigger the copy constructor, however I get the following exception (gcc 4.4.4):

error: request for member ‘say’ in ‘a1’, which is of non-class type ‘A(A)’

I believe that what's happening here is that the compiler thinks that a1 is a function definition, is this correct? If so, what is the correct way to write that particular line of code? The following appears to be a hack!

A a1(true ? A(argc) : A());

p.s. Please ignore all stylistic foobars and why exactly I want to do this...! :)


A templated constructor is never a (formal) copy constructor.

You're right that a declaration that could be a function declaration is treated as a function declaration. It's called "the most vexing parse" of C++. One workaround is to use extra parentheses, like T v(( U )).

It may be that adding an auto keyword would fix it also, I haven't tried. But since auto gains new meaning in C++0x, it's probably not a good idea to get into habit of using it even if it works for that problem in C++98.

Cheers & hth.

0

精彩评论

暂无评论...
验证码 换一张
取 消