[unordered] Visual C++ 2013 initializer_list overload failure.
Hi,
I'm getting some test failures for inserting an initializer_list into
the unordered containers:
http://www.boost.org/development/tests/trunk/developer/output/teeks99-10-win...
I don't have access to Visual C++ 12 to investigate this. This is just
a guess, but I think the problem is converting an initializer_list of
string literals to an initializer list of std::string. This works okay
with clang and g++ so I assume it's allowed. A minimal test might be
something like the following (although it might not).
#include
Daniel James wrote:
x.insert("a"); x.insert({"a"}); x.insert({"a", "b"});
Indeed; VC12 chokes on the second and third calls to insert(): "error C2668: 'thingstd::string::insert' : ambiguous call to overloaded function". Glen
On 19 October 2013 19:40, Glen Fernandes
Daniel James wrote:
x.insert("a"); x.insert({"a"}); x.insert({"a", "b"});
Indeed; VC12 chokes on the second and third calls to insert(): "error C2668: 'thingstd::string::insert' : ambiguous call to overloaded function".
Thanks. It seems that the other overloads of insert are considered because a string can be implicitly constructed from the initialiser list ('std::string{"a"}' and 'std::string{"a", "b"}' - I'm afraid I don't know the correct terminology). Clang and G++ prioritize creating std::initializer_liststd::string, while Visual C++ thinks it's ambiguous. Does anyone know which compiler is doing the right thing? I assume it's a Visual C++ bug, but I'm not sure.
Daniel James wrote:
Does anyone know which compiler is doing the right thing? I assume it's a Visual C++ bug, but I'm not sure.
I was so intrigued by string{"a","b"} (*) that I asked on c++std-core, and while so far there's been no authoritative answer as to whether VC++ is right or not (too early for that), Johannes Schaub has kindly pointed me to http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2238 and http://stackoverflow.com/q/14587436/34509 which deal with similar issues. (*) For the interested, this appears to call the InputIterator constructor, with predictable results.
I was so intrigued by string{"a","b"} (*) that I asked on c++std-core, and while so far there's been no authoritative answer as to whether VC++ is right or not...
Johannes Schaub again kindly points us out to 13.3.3.2/3 last bullet: — List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1 converts to std::initializer_list<X> for some X and L2 does not. which means that g++ and clang are right and VC++ is wrong in this specific case.
On 19 October 2013 22:35, Peter Dimov
I was so intrigued by string{"a","b"} (*) that I asked on c++std-core, and
while so far there's been no authoritative answer as to whether VC++ is right or not...
Johannes Schaub again kindly points us out to 13.3.3.2/3 last bullet:
— List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1 converts to std::initializer_list<X> for some X and L2 does not.
which means that g++ and clang are right and VC++ is wrong in this specific case.
Thanks, I'll try to work round it later this week.
Daniel James
On 19 October 2013 22:35, Peter Dimov
wrote: I was so intrigued by string{"a","b"} (*) that I asked on c++std-core, and
while so far there's been no authoritative answer as to whether VC++ is right or not...
Johannes Schaub again kindly points us out to 13.3.3.2/3 last bullet:
— List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1 converts to std::initializer_list<X> for some X and L2 does not.
which means that g++ and clang are right and VC++ is wrong in this specific case.
Thanks, I'll try to work round it later this week.
Hi Daniel, Inspecting the log seems like you tried something and then reverted the commit. Didn't it work or did you just prefer to leave the VC bug exposed in wait for it to be fixed by MS themselves? Thank you, Joaquín M López Muñoz Telefónica Digital
On 5 November 2013 11:45, Joaquin M Lopez Munoz
Inspecting the log seems like you tried something and then reverted the commit. Didn't it work or did you just prefer to leave the VC bug exposed in wait for it to be fixed by MS themselves?
It didn't work. I don't have access to the compiler so I was just
guessing. I also had made a mistake configuring boost build, so when I
thought I was testing with gcc 4.8 in C++11 mode, I wasn't. So I made
a bit of a mess and felt it was better left until later. There were
already enough problems with the compiler.
My basic idea is to do something like the following and hope that it's
possible to make the template overload match where appropriate. Might
also need to use enable_if to prevent some incorrect matches. But even
if I could get it to work, it could be very fragile. Presumably this
bug will also affect the standard containers as well, so maybe it's
not something worth fixing. At least it's a compile error, and not
silently picking the wrong overload.
#include
Daniel James
On 5 November 2013 11:45, Joaquin M Lopez Munoz
wrote: Inspecting the log seems like you tried something and then reverted the commit. Didn't it work or did you just prefer to leave the VC bug exposed in wait for it to be fixed by MS themselves?
It didn't work. [...]
My basic idea is to do something like the following and hope that it's possible to make the template overload match where appropriate. Might also need to use enable_if to prevent some incorrect matches. But even if I could get it to work, it could be very fragile. Presumably this bug will also affect the standard containers as well, so maybe it's not something worth fixing. At least it's a compile error, and not silently picking the wrong overload.
This looks serious enough, and, fwiw, there's another library (mine) suffering from seemingly the same problem: http://lists.boost.org/Archives/boost/2013/10/207529.php I've googled a bit and the only relevant reference I found is http://tinyurl.com/nq89kc2 which refers to a problem supposedly fixed in the final version of VS 2013. Maybe Stephan is reading this and can shed some light? Joaquín M López Muñoz Telefónica Digital
On 5 November 2013 12:21, Joaquin M Lopez Munoz
This looks serious enough, and, fwiw, there's another library (mine) suffering from seemingly the same problem:
Looks very similar. Also suggests I need to add some extra constructor tests.
I've googled a bit and the only relevant reference I found is
which refers to a problem supposedly fixed in the final version of VS 2013.
I think that's a different issue. In that case it seems that the conversion didn't work properly. Our problem is that it isn't seeing list initialization as a better conversion than the others.
Maybe Stephan is reading this and can shed some light?
Since Peter brought it up on c++std-core I assume someone from the compiler team would have seen that. I don't particularly want to report a bug for a compiler I don't have, but since it was confirmed that the earlier test failed, I could post that.
[Joaquin M Lopez Munoz]
Maybe Stephan is reading this and can shed some light?
[Daniel James]
Since Peter brought it up on c++std-core I assume someone from the compiler team would have seen that. I don't particularly want to report a bug for a compiler I don't have, but since it was confirmed that the earlier test failed, I could post that.
I need a self-contained repro in order to file a compiler bug. I am aware of DevDiv#796414 "Overloading op+=(char) and op+=(initializer_list<char>) should be unambiguous" which is still active. STL
On 5 November 2013 16:32, Stephan T. Lavavej
I need a self-contained repro in order to file a compiler bug. I am aware of DevDiv#796414 "Overloading op+=(char) and op+=(initializer_list<char>) should be unambiguous" which is still active.
This is the example from the start of the thread which was confirmed
to fail on Visual C++. I don't know how to find out about
"DevDiv#796414" so I don't know if it's the same issue.
#include
Stephan, I seem to recall providing a slightly similar example that
you added as repro to DevDiv#532674 when you renamed it "[Milan]
initializer_list overloading" on 2012/11/29.
Glen
On Tue, Nov 5, 2013 at 8:41 AM, Daniel James
On 5 November 2013 16:32, Stephan T. Lavavej
wrote: I need a self-contained repro in order to file a compiler bug. I am aware of DevDiv#796414 "Overloading op+=(char) and op+=(initializer_list<char>) should be unambiguous" which is still active.
This is the example from the start of the thread which was confirmed to fail on Visual C++. I don't know how to find out about "DevDiv#796414" so I don't know if it's the same issue.
#include
#include <string> template <typename T> struct thing { void insert(T const&) {} void insert(T&&) {} void insert(std::initializer_list<T>) {} };
int main() { thingstd::string x; x.insert("a"); x.insert({"a"}); x.insert({"a", "b"}); }
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[Daniel James]
I don't know how to find out about "DevDiv#796414" so I don't know if it's the same issue.
That's our internal database. (I cite bug numbers so if people ask me about them later I can look them up.)
This is the example from the start of the thread which was confirmed to fail on Visual C++.
Thanks, that's the same bug. Just in case, I've reduced your example and added it to the bug:
C:\Temp>type purr.cpp
#include
Stephan, I seem to recall providing a slightly similar example that you added as repro to DevDiv#532674 when you renamed it "[Milan] initializer_list overloading" on 2012/11/29.
Half of that was the same bug (your complex<double> example). STL
participants (5)
-
Daniel James
-
Glen Fernandes
-
Joaquin M Lopez Munoz
-
Peter Dimov
-
Stephan T. Lavavej