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.
精彩评论