использование std::initializer_list и int в качестве параметра функции приводит к неправильному переводу компилятора

Вот код, я нахожу странную вещь в std::initializer_list . Я использую вс2013. Спасибо за помощь.

struct TempStruct
{
  int t1;
  int t2;
};

int Test_A(int a, int b)
{
    std::cout << " int a, int b" << '\n';

    return 1;
}

TempStruct Test_A(std::initializer_list<int> a, std::initializer_list<int> b)
{
    std::cout << "initializer_list" << '\n';

    TempStruct Temp;

    Temp.t1 = 1;

    Temp.t2 = 2;

    return Temp;
}

int main()
{
    auto a_test = Test_A(1, 1);

    auto b_test = Test_A({ 1 }, {});

    return 1;
}

Результат(std::cout) Я хочу:

int a, int b
initializer_list

Результат(std::cout) от vs2013

int a, int b
int a, int b

В IDE vs2013, если я наведу указатель мыши на «b_test», он покажет, что b_test — это TempStruct. После сборки результата нет. Это ошибка vs2013 или неправильное использование initializer_list ?


person liangbright    schedule 03.03.2014    source источник


Ответы (1)


Это утверждение:

Test_A({ 1 }, {});

Можно интерпретировать как 2 списка инициализаторов, содержащих 1 и ничего не содержащих, но также можно интерпретировать как:

Test_A(int{ 1 }, int{});

Это так называемый унифицированный синтаксис инициализации. Intellisense имеет собственную реализацию «компилятора» и часто показывает ошибки там, где их нет, или показывает неправильные типы. Это часто происходит с новыми функциями C++11.

Вы можете попробовать использовать двойные фигурные скобки для устранения неоднозначности:

Test_A({{ 1 }}, {{}});

Я не могу проверить это на данный момент, хотя Visual Studio и iPad не очень хорошо сочетаются;)

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

person Excelcius    schedule 03.03.2014
comment
Спасибо. Но я думаю, что если есть initializer_list, определенный как входной параметр функции, компилятор должен сначала сопоставить эту функцию. Теперь я должен предоставить два типа функций с разными именами. - person liangbright; 28.03.2014
comment
@liangbright Нет, не надо! Вы можете написать это с двойными фигурными скобками, как я сказал в своем ответе. Теперь у меня было время проверить это, это работает. Если вы вызовете Test_A({{1}}, {{}}), он правильно напечатает "initializer_list". Это ошибка в стандарте С++ 11, если хотите. Правила, когда inializer_lists имеют приоритет и когда необходимы двойные скобки, будут ослаблены в C++14. См. также этот документ по теме: open- std.org/JTC1/SC22/WG21/docs/papers/2013/n3526.html - person Excelcius; 28.03.2014