0

This code compiles if the std::copy is commented out, and the atc initializer is uncommented.

class MyClass {
  MyClass( OtherClass* poc_in, std::initializer_list<ThirdClass> iltc) :
    poc( poc_in)
    //, atc(iltc)
  {
    std::copy( iltc.begin(), iltc.end(), atc );
  }

  OtherClass* poc;
  std::vector<ThirdClass> atc;
}

However, as written I get:

In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/algorithm:61:0,
                 from ../../../src/tester/main.cpp:5:
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h: In instantiation of '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const ThirdClass*; _OI = std::vector<ThirdClass>]':
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:422:45:   required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const ThirdClass*; _OI = std::vector<ThirdClass>]'
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:455:8:   required from '_OI std::copy(_II, _II, _OI) [with _II = const ThirdClass*; _OI = std::vector<ThirdClass>]'
../../../src/tester/main.cpp:75:59:   required from here
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:378:57: error: no type named 'value_type' in 'struct std::iterator_traits<std::vector<ThirdClass> >'
       typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
                                                         ^~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:383:9: error: no type named 'value_type' in 'struct std::iterator_traits<std::vector<ThirdClass> >'
       const bool __simple = (__is_trivial(_ValueTypeI)
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~
                       && __is_pointer<_II>::__value
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       && __is_pointer<_OI>::__value
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         && __are_same<_ValueTypeI, _ValueTypeO>::__value);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I've read a half-dozen similar questions on Stack Overflow but none sheds light on why this version is unloved. Any suggestions?

Swiss Frank
  • 1,985
  • 15
  • 33

1 Answers1

3

This has nothing to do with initialiser lists.

You're using std::copy wrong.

That third argument should be an output iterator, not a vector.

Try using std::back_inserter:

std::copy( iltc.begin(), iltc.end(), std::back_inserter(atc) );

The compilation error is admittedly a little esoteric, but it's saying that the compiler is looking for the member value_type (which all most iterators have) in the traits helper for the type of the argument you gave it (a vector), which doesn't exist (because a vector isn't an iterator).

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • 1
    There's even an example of this on [the cppreference page for `std::copy`](https://en.cppreference.com/w/cpp/algorithm/copy)! There was no need to read a half-dozen similar questions on Stack Overflow... – Asteroids With Wings Oct 05 '20 at 17:14
  • thanks. I had read that page too but didn't realize my code didn't match what was written. Besides the back_inserter() you suggest here, what about atc.begin()? That seems to be in several examples. Should it work the same and do you see pluses or minuses either way? – Swiss Frank Oct 06 '20 at 04:22
  • 1
    The main minus is that it will not work properly. You do not have any elements in the vector, so you cannot write to a sequence starting at `atc.begin()`. You could do that if you'd pre-filled the vector with elements ready to overwrite. But, to create _new_ elements, `back_inserter` is what you need (hence its name). – Asteroids With Wings Oct 06 '20 at 12:34