jmeseguerdepaz
jmeseguerdepaz

Reputation: 332

Trouble understanding whence a copy constructor came

I have the following small code:

template <typename T>
class V
{
    public:
        T x;

    explicit V(T & _x)
    :x(_x){}

};

int main()
{
    V<float> b(1.0f); // fails
    return 0;
}

And it happens to fail. The message returned by g++ 4.4.5 is:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
../main.cpp: In function ‘int main()’:
../main.cpp:19: error: no matching function for call to ‘V<float>::V(float)’
../main.cpp:10: note: candidates are: V<T>::V(T&) [with T = float]
../main.cpp:6: note: V<float>::V(const V<float>&)

The thing is... whence the second constructor came? I really have no clue...

Upvotes: 2

Views: 160

Answers (2)

Michael Burr
Michael Burr

Reputation: 340306

Other answers discuss why you're getting a compile-time failure (which is what most questions are about when such failures are the most prominent part of the question). However. regarding your explicit question, "whence the second constructor came?":

12.8/4 "Copying class objects" of standard says:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly.

If you'd like to avoid the implicit copy-ctor from being used, one of a few 'non-copyable' idioms can be used (such as boost::noncopyable): http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin

Upvotes: 6

Naveen
Naveen

Reputation: 73473

Compiler has supplied a copy constructor and assignment operator to your class. It is trying to match that copy constructor with your statement in main. The problem with this code is that in the constructor of class V you are taking the parameter as a non-const reference. When you do V<float> b(1.0f), compiler will create an unnamed temporary variable of type float for the value 1.0f. However, this unnamed temporary can not be bound to a non-const reference, it can be bound only to a const reference. Hence you need to change the constructor signature to explicit V(const T & _x).

Upvotes: 4

Related Questions