Как инициализировать элементы unordered_map <string, unordered_set <string>>, используя список инициализаторов? - PullRequest
3 голосов
/ 26 июня 2019

У меня есть этот класс

class A {
    unordered_map<string, unordered_set<string>> n_;
  public:
    A(unordered_map<string, unordered_set<string>>& n) : n_{n} {}
};

И я хочу иметь возможность использовать конструктор с этим синтаксисом

int main() {
    A a{{"C", {"A", "B"}}};
    return 0;
}

Но, как написано сейчас, я получаю сообщение об ошибке

error: no matching function for call to `‘A::A(<brace-enclosed initializer list>)’ A a{{"C", {"A", "B"}}};`

Как это можно исправить?

Ответы [ 4 ]

7 голосов
/ 26 июня 2019

Вам нужно добавить еще один {} для него. И обратите внимание, что временное не может быть связано с lvalue-ссылкой на неконстантный. (Они могут быть связаны с lvalue-ссылками на const или rvalue-ссылками.) Например,

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

Полагаю, вы можете пропустить {} для элементов (std::pair) unordered_map; Аналогичным образом, если вы хотите создать unordered_map, содержащий два элемента, вы можете написать его как

A b{{{"C", {"A", "B"}}, {"F", {"D", "E"}}}};

ЖИТЬ

4 голосов
/ 26 июня 2019

Я хочу иметь возможность использовать конструктор с этим синтаксисом

Вы можете предоставить std :: initializer_list конструктор для выполнения работы

#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 } {}
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
};
Преимущество

в том, что для инициализации списка не требуется дополнительная пара {}. Например карты с двумя записями:

A a{
    {"C", {"A", "B"}},
    {"D", {"E", "F"}},
}; // do not require extra braces now!

( см. В прямом эфире )

3 голосов
/ 26 июня 2019

Помимо правильного ответа Джарода, вам не хватает одного набора фигурных скобок:

int main() {
    A a{{{"C", {"A", "B"}}}};
    return 0;
}

Из самых внутренних:

Вам нужно инициализировать std::unordered_set:

{"A", "B"}

Используйте этот набор в случае std::pair

{"C", {"A", "B"}}

Используйте эту пару для инициализации std::unordered_map:

{{"C", {"A", "B"}}}

Используйте эту карту для инициализацииобъект A:

A a{{{"C", {"A", "B"}}}};
2 голосов
/ 26 июня 2019

Временный не может привязаться к неконстантной (lvalue) ссылке.

Вы можете изменить конструктор на

A(const unordered_map<string, unordered_set<string>>& n) : n_{n} {}

или

A(unordered_map<string, unordered_set<string>>&& n) : n_{std::move(n)} {}

или

A(unordered_map<string, unordered_set<string>> n) : n_{std::move(n)} {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...