2017-02-08 11 views
3

У меня есть этот кусок кода, где я пытаюсь впихнуть в векторе уже построенный элемент из unordered_map:Не удается отодвинуть объект класса из конструктора

class A { 
public: 
    A(const std::string& a) {} 
} 

int main() { 
    std::unordered_map<std::string, A> map {{"A", A("A")}, {"B", A("B")}}; 
    std::vector<A> vec; 
    vec.push_back(map["A"]); 
} 

Но почему я получаю ошибки, связанные с в вектор-х push_back:

/usr/local/include/c++/6.3.0/tuple:1586:70: error: no matching function for call to 'A::A()' 
     second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 
                    ^
main.cpp:8:9: note: candidate: A::A(const string&) 
     A(const std::string& a) {} 
     ^
main.cpp:8:9: note: candidate expects 1 argument, 0 provided 
main.cpp:6:7: note: candidate: constexpr A::A(const A&) 
class A { 
    ^
main.cpp:6:7: note: candidate expects 1 argument, 0 provided 
main.cpp:6:7: note: candidate: constexpr A::A(A&&) 
main.cpp:6:7: note: candidate expects 1 argument, 0 provided 
+0

Обратите внимание, что если вы не хотите, чтобы создать конструктор по умолчанию для вашего типа (или это невозможно), вы можете использовать 'карту :: найти()' метод вместо 'оператора []' - бывшее имеет возможность возвращать «no element found» ('map :: end()') – yeputons

ответ

3

Вопрос заключается в том, что при использовании std::unordered_map::operator[](ref) вашей mapped_type (A) должен быть default constructible, то key_type должен быть move constructible, который не является проблемой, с std::string в вашем примере.

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

class A { 
public: 
    A(const std::string& a) {} 
    A() {} // Default constructor 
}; 

int main() { 
    std::unordered_map<std::string, A> map {{"A", A("A")}, {"B", A("B")}}; 
    std::vector<A> vec; 
    vec.push_back(map["A"]); // Requires default constructor 
    vec.push_back(map.at("A")); // Do NOT requires default constructor 
} 
+0

Не 'DefaultInsertable'. Это означает, что объект напрямую сконструирован конструктором 'construct', что не так. –

+0

@ T.C. Обновлено, ответ. – Jonas

2

std::map::operator[]requires отображенный типа (в вашем случае, A) быть default-insertable, так что вы должны предоставить конструктор по умолчанию, который вы не имеете, для examp ле:

class A { 
public: 
    A(){} 
    A(const std::string& a) {} 
} 
3

С вопросом, имеющим C++ 11 тегом, вышеуказанные ответы могли бы упомянуть, что вам не нужны фактическую реализация конструкторы по умолчанию, но вы можете использовать =default спецификатор, чтобы передать, что это только причина, в которой это необходимо.

class A { 
public: 
    A() = default; 
    A(const std::string& a) {} 
}