简体   繁体   中英

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

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 constructor, ie

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());

ps 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM