Hi all,
Is it this behavior correct ?
//Code ----------------------
#include <initializer_list>
#include
#include
#include
using namespace std;
void foo( initializer_list<typename vector::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
#include
#include
#include
using namespace std;
void foo( initializer_list<typename vector::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
#include
#include
#include
using namespace std;
void foo( initializer_list<typename vector::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.