Как я могу инициализировать карту без явного вызова явного конструктора? - PullRequest
2 голосов
/ 02 мая 2019

Я пытаюсь инициализировать std::map списком инициализаторов (в производстве это инициализатор членов класса, но мой минимальный ошибочный пример приведен ниже). Учитывая

#include <map>

struct Cfg {};

struct Alg
{
    explicit Alg(Cfg const&) {}
};

using MyMap = std::map<int, Alg>;

int main()
{

    Cfg cfg;

    MyMap m = {
        {1, {cfg}},      // error #1
        {2, cfg},        // error #2
        {3, Alg(cfg)},   // works fine
    };

  return 0;
}

При компиляции ошибка # 1:

foo.cc: In function ‘int main()’:
foo.cc:22:5: error: converting to ‘const Alg’ from initializer list would use 
explicit constructor ‘Alg::Alg(const Cfg&)’
     };
     ^

Это довольно просто. Передача Cfg в инициализатор требует преобразования, и явный конструктор запрещает его.

Ошибка № 2

foo.cc: In function ‘int main()’:
foo.cc:22:5: error: converting to ‘std::pair<const int, Alg>’ from initializer list would use explicit constructor ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U1 = int; _U2 = Cfg&; typename std::enable_if<(std::_PCC<true, _T1, _T2>::_MoveConstructiblePair<_U1, _U2>() && (! std::_PCC<true, _T1, _T2>::_ImplicitlyMoveConvertiblePair<_U1, _U2>())), bool>::type <anonymous> = 0; _T1 = const int; _T2 = Alg]’
     };
     ^

Это немного более запутанно. Я думаю, что ошибка говорит о неявном вызове явного конструктора std::pair; читая документацию для std::pair, я теряюсь в том, какие конструкторы являются явными, когда.

Третий случай - явная конструкция. По причинам ремонтопригодности я бы предпочел этого не делать.

Похоже, я читал, что многие нелогичные проблемы со списком инициализаторов можно решить, добавив дополнительные скобки (грубое упрощение), но я признаюсь, что на данный момент я потерян.

Если я удаляю квалификацию explicit конструктора Alg, все три случая компилируются. Однако я не уверен, что имеет смысл предоставлять неявное преобразование только для упрощения списка инициализаторов.

Есть ли способ инициализировать элементы моей карты без явного создания элементов Alg? Использование g ++ 7.3

1 Ответ

1 голос
/ 02 мая 2019

Насколько я знаю, нет никакого способа указать тип Alg.Так или иначе, это намерение конструкторов explicit.Просто ради [я не знаю, что здесь сказать] вы, тем не менее, можете вызвать конструктор на месте std::pair, как показано ниже.

MyMap m{{std::piecewise_construct, std::forward_as_tuple(1), std::tie(cfg)}};

Таким образом, вы не можетенужно набрать Alg, какой вид отвечает на ваши вопросы.Кроме того, делайте это только в том случае, если вы ненавидите себя и своих коллег.

Примечание: конструктор на месте std::pair фактически присутствует, чтобы допускать не копируемые, неподвижные типы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...