Reputation: 613
I have this class
class A {
unordered_map<string, unordered_set<string>> n_;
public:
A(unordered_map<string, unordered_set<string>>& n) : n_{n} {}
};
And I want to be able to use the constructor with that syntax
int main() {
A a{{"C", {"A", "B"}}};
return 0;
}
But in the way it's written now, I'm getting error
error: no matching function for call to `‘A::A(<brace-enclosed initializer list>)’ A a{{"C", {"A", "B"}}};`
How can it be fixed?
Upvotes: 4
Views: 2539
Reputation: 32852
I want to be able to use the constructor with that syntax
You can provide an std::initializer_list constructor to do the job
#include <initializer_list>
class A
{
using MapType = std::unordered_map<std::string, std::unordered_set<std::string>>;
MapType n_;
public:
A(std::initializer_list<MapType::value_type> n) : n_{ n } {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
};
which has the advantage that list initialization does not require an extra pair of {}
.
For example maps with two entries:
A a{
{"C", {"A", "B"}},
{"D", {"E", "F"}},
}; // do not require extra braces now!
Upvotes: 4
Reputation: 172924
You need to add one more {}
for it. And note that temporary can't be bound to lvalue-reference to non-const. (They could be bound to lvalue-references to const or rvalue-references.) e.g.
class A {
unordered_map<string, unordered_set<string>> n_;
public:
A(const unordered_map<string, unordered_set<string>>& n) : n_{n} {}
//^^^^^
};
int main() {
A a{{{"C", {"A", "B"}}}};
// ^^^ ^^^ elements of unordered_set
// ^^^^^^^^^^ for the unordered_set
// ^^^^^^^^^^^^^^^^^ elements (std::pair) of unordered_map (only one here)
// ^^^^^^^^^^^^^^^^^^^ for the unordered_map
// ^^^^^^^^^^^^^^^^^^^^^ for A
return 0;
}
I guess you might miss the {}
for the elements (std::pair
) of the unordered_map
; in a similar fashion, if you want to make the unordered_map
containing two elements, you can write it as
A b{{{"C", {"A", "B"}}, {"F", {"D", "E"}}}};
Upvotes: 8
Reputation: 22219
On top of Jarod's (correct) answer, you are missing one set of curly braces:
int main() {
A a{{{"C", {"A", "B"}}}};
return 0;
}
From the innermost ones:
You need to initialize std::unordered_set
:
{"A", "B"}
Use that set in instance of std::pair
{"C", {"A", "B"}}
Use that pair to initialize std::unordered_map
:
{{"C", {"A", "B"}}}
Use that map to initialize an object of A
:
A a{{{"C", {"A", "B"}}}};
Upvotes: 3
Reputation: 217293
Temporary cannot bind to non-const (lvalue) reference.
You might change constructor to
A(const unordered_map<string, unordered_set<string>>& n) : n_{n} {}
or
A(unordered_map<string, unordered_set<string>>&& n) : n_{std::move(n)} {}
or
A(unordered_map<string, unordered_set<string>> n) : n_{std::move(n)} {}
Upvotes: 2