Как отличить вектор <> от карты <> при инициализации вложенного списка? - PullRequest
3 голосов
/ 08 апреля 2019

Рассмотрим класс, определенный как:

class C {
    public:
    C(std::vector<std::string>) {};           // (1)
    C(std::map<std::string, std::string>) {}; // (2)
};

Затем два его экземпляра, созданные с использованием инициализаторов списка, таких как:

C A({ "A", "B" });
C B({ { "A", "B" }, { "C", "D" } });

Я ожидаю, что объект A будет использовать конструктор (1), а объект B будет проходить через (2). Но это не так, и я получаю следующий вывод: error: call to constructor of 'C' is ambiguous.

Кроме того, если я попытаюсь объявить эти экземпляры как:

C A = { "A", "B" };
C B = { { "A", "B" }, { "C", "D" } };

Вместо этого происходит сбой: error: no matching constructor for initialization of 'C'.

Что происходит?

Как мне достичь желаемого поведения? (A -> (1), B -> (2)) Возможно, каким-то образом использовать SFINAE?

1 Ответ

0 голосов
/ 08 апреля 2019

Я добился того, что вы хотите, следующим образом:

class C {
    public:
    C(std::vector<std::string>) { std::cout << "here1" << std::endl; }           // (1)
    C(std::map<std::string, std::string>) { std::cout << "here2" << std::endl; } // (2)
};

int main()
{
    C A = C( { {"A"}, {"B"} });
    C B = C( std::map<std::string, std::string> { {"A", "B"}, {"C", "D"} } );
    // or C B = C( { std::make_pair("A", "B"), std::make_pair("C", "D") } );
}

EDITED (с использованием унифицированной инициализации)

...