[cfe-dev] initializer_list deduction

David Blaikie dblaikie at gmail.com
Wed May 9 12:57:32 PDT 2012


On Wed, May 9, 2012 at 12:24 PM, Fernando Pelliccioni
<fpelliccioni at gmail.com> wrote:
>
>
> On Wed, May 9, 2012 at 3:27 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>
>> On Wed, May 9, 2012 at 11:18 AM, Fernando Pelliccioni
>> <fpelliccioni at gmail.com> wrote:
>> > Hi all,
>> >
>> > Is it this behavior correct ?
>> >
>> > //Code ----------------------
>> > #include <initializer_list>
>> > #include <iostream>
>> > #include <string>
>> > #include <vector>
>> >
>> > using namespace std;
>> >
>> > void foo( initializer_list<typename vector<string>::value_type> list )
>> > {
>> >     for (auto& item : list)
>> >     {
>> >         cout << item << endl;
>> >     }
>> > }
>> >
>> > int main( /* int argc, char* argv[] */ )
>> > {
>> >     foo( { {"k0", "v0"}, {"k1", "v1"} } );
>> >     return 0;
>> > }
>> >
>> > //End code ----------------------
>> >
>> >
>> > $ clang++ --version
>> > clang version 3.1 (trunk 155038)
>> > Target: i386-pc-linux-gnu
>> > Thread model: posix
>> >
>> > $ clang++ -std=c++11 initializer_list_test.cpp
>> > $ ./a.out
>> > k0
>> > k1
>> >
>> > ------------------------------------------
>> >
>> > I would have expected that the initializer_list be deduced to something
>> > like
>> > an associative container (a compile time error).
>>
>> I believe you're calling the std::string(Iterator begin, Iterator end)
>> constructor. As you could with this code:
>>
>> std::string s{"k0", "v0"};
>>
>> (or even C++03 code: std::string s("k0", "v0"); )
>
>
>
> Oh, you're right!
>
>>
>>
>> You probably got luck with the string constant layout & ran into "v0"
>> from "k0" - but I suspect the length of your strings is 3, not 2
>> (including the null character between "v0" and "k0")
>
>
>
> But... I'm  concerned about the ambiguous resolution in this case ...
>
>
> //Code ----------------------
> #include <initializer_list>
> #include <iostream>
> #include <string>
> #include <vector>
> #include <map>
>
> using namespace std;
>
> void foo( initializer_list<typename vector<string>::value_type> list )
> {
> for (auto& item : list)
> {
> cout << item << endl;
> }
> }
>
> void foo( initializer_list<typename map<string, string>::value_type> list )
> {
> for (auto& item : list)
> {
> cout << item.first << endl;
> }
> }
>
> int main( /* int argc, char* argv[] */ )
> {
> foo( { {"k0", "v0"}, {"k1", "v1"} } );
> return 0;
> }
>
> //End code ----------------------
>
>
> It seems that no solution.

Are you concerned that Clang has implemented the resolution
incorrectly? or that the standard has specified it incorrectly?

The same ambiguity exists without initializer_lists, though:

void foo(std::string);
void foo(std::pair<std::string, std::string>);

foo({"k0", "v0"});




More information about the cfe-dev mailing list