"result type must be constructible from value type of input range" when creating a std::vector

Viewed 15433

I have a class member that looks like this

class Controller {
    protected:
    // other stuff
    std::vector<Task<event_t, stackDepth>> taskHandlers; 

    //some more stuf
}

The Task class is non-defaultConstructible, non-copyConstructible, non-copyAssignable but is moveConstructible and moveAssignable. Everything I could read (notably, std::vector documentation) leads me to think that this should compile, but the error list looks like this (full output here) :

/usr/include/c++/9/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range
  127 |       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
      |                                                                        ^~~~~

Making Task defaultConstructible did not help. The error points to the definition of the class Controller. I am using GCC 9.3.0 in c++17 mode. Did I do anything wrong ?

2 Answers

My best guess, given the current information, is that you messed up the move constructor syntax somehow - working example using just emplace_back:

The below compiles fine, link to godbolt:

#include <vector>

class X
{
public:
    X(int i) : i_(i){}
    X() = delete;
    X(const X&) = delete;
    X(X&&) = default;//change this to 'delete' will give a similar compiler error
private:
    int i_;
};


int main() { 
    std::vector<X> x;
    x.emplace_back(5);
}

to reproduce the error result type must be constructible from value type of input range

godbolt

#include <vector>
#include <string>
#include <iostream>

int main() {

typedef std::vector<std::string> StrVec;

StrVec s1("a", "b"); // error
// stl_uninitialized.h:127:7: error: static_assert failed due to requirement 'is_constructible<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const char &>::value' "result type must be constructible from value type of input range"

//StrVec s2("a", "b", "c"); // error
// error: no matching constructor for initialization of 'StrVec' (aka 'vector<basic_string<char> >')

StrVec s3({"a", "b"}); // ok
StrVec s4({"a", "b", "c"}); // ok

typedef std::vector<int> IntVec;

IntVec i1(1, 2); // silent error
for (auto i : i1) {
    std::cout << "i = " << i << '\n';
}
// silent error:
// output:
// i = 2
// expected:
// i = 1
// i = 2

//IntVec i2(1, 2, 3); // error
// error: no matching constructor for initialization of 'IntVec' (aka 'vector<int>')

IntVec i3({1, 2}); // ok
IntVec i4({1, 2, 3}); // ok

}
Related