Reputation: 229
I have this piece code where I try to push into a vector an already constructed element from an 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"]);
}
But why I'm getting errors regarding to the the vector's 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
Upvotes: 3
Views: 1097
Reputation: 7017
The issue is that when using std::unordered_map::operator[]
(ref) your mapped_type
(A
) must be default constructible, the key_type
must be move constructible which is not an issue with std::string
in your example.
#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
}
Upvotes: 3
Reputation: 10756
With the question having a C++11 tag, the above answers could mention that you don't need an actual implementation of a default constructor, but that you can use the =default
specifier to convey that is the only reason it's needed.
class A {
public:
A() = default;
A(const std::string& a) {}
}
Upvotes: 3
Reputation: 29966
std::map::operator[]
requires the mapped type (in your case, A
) to be default-insertable, so you have to provide a default constructor, which you have not, for example:
class A {
public:
A(){}
A(const std::string& a) {}
}
Upvotes: 2