2

Here is the code, I find a strange thing about std::initializer_list . I use vs2013. Thanks for help.

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

Result(std::cout) I want:

int a, int b
initializer_list

Result(std::cout) from vs2013

int a, int b
int a, int b

In the vs2013 IDE, if I move mouse on "b_test", it shows b_test is TempStruct. After build, the result isn't. Is this a bug of vs2013 or miss-use of initializer_list ?

1 Answer 1

1

This statement:

Test_A({ 1 }, {});

Can be interpreted as 2 initializer lists containing 1 and containing nothing, but it can also be interpreted as:

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

This is the so-called uniform initialization syntax. The Intellisense has its own "compiler" implementation and often shows errors where there are none or shows wrong types. This happens a lot with the new C++11 features.

You can try using double braces to disambiguate:

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

I can't verify this at the moment though, Visual Studio and iPad don't mix very well ;)

You should also consider accepting only initializer lists and handle the special case when only 1 item is passed, as most callers will probably be confused what the difference between these 2 overloads is.

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

2 Comments

Thanks. But I think if there is initializer_list defined as input parameter of a function , compiler should match that function first.Now, I have to provide two kinds of functions with different names.
@liangbright No you don't have to! You can write it with double braces as I said in my answer. I now had time to test this, it works. If you call Test_A({{1}}, {{}}) it will correctly print "initializer_list". This is a "bug" in the C++11 standard if you want to call it that. The rules for when intializer_lists take precedence and when double-braces are needed will be relaxed in C++14. See also this paper on the topic: open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3526.html

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.