3

Class Foo only has a default constructor and a copy constructor. A vector of size 10 initialized by object of type Foo is somehow incorrect.

#include <iostream>
#include <vector>

class Foo
{
    public:
        Foo() = default; // Error1
        Foo(Foo& foo) {  // Error2
            std::cout << "copied" << std::endl;
        }

};

int main( void )
{
    Foo f;
    std::vector<Foo> vec(10, f); // Error3
    return 0;
}

There are 3 errors for the sample code above:

Error1: candidate constructor not viable: requires 0 arguments, but 1 was provided

Error2: candidate constructor not viable: 1st argument ('const Foo') would lose const qualifier

Error3: in instantiation of member function 'std::__1::vector >::vector' requested here

When I remove the copy constructor or the vector in the main function, there are no errors.

Question:

Which part of the code is wrong and why?

p.s.

When the vector definition is replaced by Foo ff(f), errors are gone as well. Is the const qualifier is request by the vector?

6
  • 3
    A copy constructor that modifies the thing it copies from looks strange. Commented Nov 28, 2018 at 13:41
  • 4
    Read the second error carefully. Commented Nov 28, 2018 at 13:43
  • 1
    Try making the copy constructor Foo(const Foo& foo) Commented Nov 28, 2018 at 13:44
  • 1
    @SLN I guess std::vector adds const before copying to ensure the initial object is not changed in some weird copy constructors like the ones juanchopanza had in mind while posting his comment. Commented Nov 28, 2018 at 13:56
  • 1
    @SLN - Think of it like this. If I gave you my lecture to notes to copy after you missed a class, it'd be pretty poor form to doodle all over my notebook, won't it? Commented Nov 28, 2018 at 14:05

3 Answers 3

4

Look at the signature of the invoked constructor of std::vector:

vector(size_type n, const T& value, const Allocator& = Allocator());

The argument f is passed by const reference (parameter value). That parameter therefore cannot be bound to non-const parameter foo of type Foo& of Foo's copy constructor.


Same (simpler) case:

Foo f;
const Foo& value = f;
Foo& foo = value;  // error
Sign up to request clarification or add additional context in comments.

1 Comment

@bolov - Sorry what? You can't bind a non-const reference to an object that is const or is referred to by a const reference. This answer is perfectly correct.
1

The constructor you use is std::vector::vector (2)

vector( size_type count, 
                 const T& value,
                 const Allocator& alloc = Allocator());

The parameter value which will be copied inside the constructor is const, and because your copy constructor cannot copy from const the implementation of the constructor cannot create copies to fill the vector.

Comments

0

The constructor documentation of std::vector shows the following signature:

explicit vector (size_type n, const value_type& val = value_type(),
             const allocator_type& alloc = allocator_type());

This shows that it requires val to be a const reference. Because it most likely won't cut this const in it's internal processing it seems to pass val like this to the copy constructor. Because Foo's copy constructor expects an non-const reference to be passed val would lose it's const qualifier. Because this is not allowed the compiler raises the error

Error: candidate constructor not viable: 1st argument ('const Foo') would lose const qualifier

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.