[cfe-dev] initializer_list deduction

Fernando Pelliccioni fpelliccioni at gmail.com
Wed May 9 16:33:41 PDT 2012


On Wed, May 9, 2012 at 4:57 PM, David Blaikie <dblaikie at gmail.com> wrote:

> 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?
>
>
I'm not really worried about either.
I want to write something like this in C++


my_type variables = {
  {"var"   , "value"}
, {"hello" , "Hello World!"}
, {"empty" , ""}
, {"path"  , "/foo/bar"}
, {"x"     , "1024"}
, {"y"     , "768"}
, {"list"  , { "val1", "val2", "val3" }}
, {"keys"  , { {"key1", "val1"}, { "key2" "val2"} } }
};

Is like a sum type (variant).

The same ambiguity exists without initializer_lists, though:
>
> void foo(std::string);
> void foo(std::pair<std::string, std::string>);
>
> foo({"k0", "v0"});
>


The most simple and short way I found to avoid the ambiguity was as follows
...

#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 )
{
cout << "map!!";
for (auto& item : list)
{
cout << item.first << endl;
}
}

string operator"" _s (const char* p, size_t n)
{
return string(p,n);
}

int main( /* int argc, char* argv[] */ )
{
foo( { {"k0"_s, "v0"}, {"k1", "v1"} } );
foo( {"a", "b"} );

return 0;
}


I think not so bad.

Thanks and regards,
Fernando.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120509/8ed1727e/attachment.html>


More information about the cfe-dev mailing list