4

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?

1
  • Maybe you should use a const reference, instead Commented Jun 26, 2019 at 12:43

4 Answers 4

8

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"}}}};

LIVE

Sign up to request clarification or add additional context in comments.

Comments

4

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!

(See Live)

Comments

3

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"}}}};

Comments

2

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)} {}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.