10

I have a class (Uniform) that has a constructor with 2 parameters, and a default copy constructor (it only contains int, floats, a std::vector and a std::map). I created a

std::vector<Uniform> uniforms

that I want to fill using the

uniforms.push_back()

line. I use this code to do that (the 2nd line is just here to test the copy constructor, as it currently fails)

Uniform uni(uniform_name,type);
Uniform uni2=uni;
uniforms.push_back(uni2);

The default constructor works fine, the "uni2=uni" compiles without problem (so the default copy constructor is OK too), but the push_back returns (using g++ as a compiler):

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/ext/new_allocator.h:108:9: erreur: no matching function for call to ‘Uniform::Uniform(const Uniform&)’

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/ext/new_allocator.h:108:9: note: candidates are:

./inc/uniform.h:16:5: note: Uniform::Uniform(std::string, Uniform_Type)

./inc/uniform.h:16:5: note: candidate expects 2 arguments, 1 provided

./inc/uniform.h:14:7: note: Uniform::Uniform(Uniform&)

./inc/uniform.h:14:7: note: no known conversion for argument 1 from ‘const Uniform’ to ‘Uniform&’

Thanks :)

Community
  • 1
  • 1
Tuxer
  • 103
  • 1
  • 1
  • 4
  • 1
    Firstly, where is the definition of `Uniform`? Secondly, stop abusing the term "default". "Default" has a very specific meaning in C++. "Default constructor" and "copy constructor" are two completely different things in C++. In your case default constructor is not involved at all. – AnT stands with Russia Jun 10 '11 at 18:40
  • You should also look at this question, as you have exactly the same problem: http://stackoverflow.com/questions/6302899/using-stdcopy-error-c2679-cant-find-correct-binary-operator/6303073#6303073 – littleadv Jun 10 '11 at 18:42
  • As AndreyT said, please post code (ideally that can be compiled to produce the symptoms described) instead of describing the code. – Michael Burr Jun 10 '11 at 18:44

4 Answers4

13

When you say "default copy constructor" (which generally makes little sense), I assume you mean "implicitly-declared copy constructor" or "compiler-provided copy constructor"

The exact signature of the compiler-provided copy constructor will depend on the contents of your Uniform class. It could be Uniform::Uniform(const Uniform &) or Uniform::Uniform(Uniform &) depending, again, on the details of Uniform (which you didn't provide).

For example, if your Uniform includes a subobject (base or member) of type T, whose copy constructor is declared as T::T(T &) (no const), then Uniform's implicit constructor will also be implicitly declared as Uniform::Uniform(Uniform &) (no const).

A full specification can be found in the language standard (12.8/5)

The implicitly-declared copy constructor for a class X will have the form

X::X(const X&)

if

— each direct or virtual base class B of X has a copy constructor whose first parameter is of type const B& or const volatile B&, and

— for all the nonstatic data members of X that are of a class type M (or array thereof), each such class type has a copy constructor whose first parameter is of type const M& or const volatile M&.

Otherwise, the implicitly declared copy constructor will have the form

X::X(X&)

An implicitly-declared copy constructor is an inline public member of its class.

The push_back implementation needs Uniform::Uniform(const Uniform &), but something in your class causes it to be Uniform::Uniform(Uniform &). Hence the error. There's no way to say what it is without seeing the definition of your Uniform.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 1
    Please excuse my ignorance, but what sort of thing in `Uniform` might cause the compiler to generate a copy constructor that takes a non-const reference parameter? – HighCommander4 Jun 10 '11 at 18:48
  • 5
    @HighCommander - if the class contains members that have copy constructors that don't have a `const` qualified parameter then the implicitly-declared copy constructor will also not be `const` qualified. – Michael Burr Jun 10 '11 at 18:50
1

Your copy constructor needs to take its argument as a const reference:

Uniform::Uniform(const Uniform& other)
Xeo
  • 129,499
  • 52
  • 291
  • 397
1

Your copy constructor should accept const Uniform& and not Uniform& as the one you have does.

littleadv
  • 20,100
  • 2
  • 36
  • 50
0

You failed to include the copy constructor (sic!!!) but you must have defined it wrongly:

Uniform::Uniform(Uniform&)
{
     ....
}

should be (note the const)

Uniform::Uniform(const Uniform&)
{
     ....
}
sehe
  • 374,641
  • 47
  • 450
  • 633