Bug 52522 - Overloaded functions called with initializer lists considered ambiguous
Overloaded functions called with initializer lists considered ambiguous
Status: RESOLVED DUPLICATE of bug 43813
Product: gcc
Classification: Unclassified
Component: c++
4.6.3
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-03-07 17:17 UTC by Dave Steffen
Modified: 2012-03-08 18:34 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Steffen 2012-03-07 17:17:24 UTC
Consider:

#include <vector>
using std::vector;
class Matrix{};
class Vector{};

Matrix horizontalConcat(const std::vector<Vector>& vectors);
Matrix horizontalConcat(const std::vector<Matrix>& matrices);

int main()
{
 Matrix a,b;
 horizontalConcat({a,b});
}

GCC 4.4 and 4.5 in C++0X mode (E.G., g++ testA.cpp -c -ansi -std=c++0x ) accept this code and do the right thing.  However, 4.6.3 produces:

/usr/local/compilers/4.6/bin/g++ testA.cpp -c -ansi -std=c++0x 

estA.cpp: In function ‘int main()’:
testA.cpp:25:24: error: call of overloaded ‘horizontalConcat(<brace-enclosed initializer list>)’ is ambiguous
testA.cpp:25:24: note: candidates are:
testA.cpp:12:8: note: Matrix horizontalConcat(const std::vector<Vector>&)
testA.cpp:13:8: note: Matrix horizontalConcat(const std::vector<Matrix>&)

However, sending an initializer list containing 3 or more Matrices works fine.  Also, removing the vector<Vector> overloaded function removes the warning.

In principle there could be some ambiguity, when using an initializer list of two elements, between calling vector's initializer list ctor or calling one of its other ctors, but here I don't see that either, since vector<Matrix> doesn't have a ctor that takes two matrices.

At any rate, either GCC 4.6 is incorrectly concluding that the function call is ambiguous, or it's producing a very confusing error message.

Thanks very much.
Comment 1 Jonathan Wakely 2012-03-07 18:32:56 UTC
Clang gives a very similar result, so I'm not convinced it's a bug:

t.cc:12:2: error: call to 'horizontalConcat' is ambiguous
 horizontalConcat({a,b});
 ^~~~~~~~~~~~~~~~
t.cc:6:8: note: candidate function
Matrix horizontalConcat(const std::vector<Vector>& vectors);
       ^
t.cc:7:8: note: candidate function
Matrix horizontalConcat(const std::vector<Matrix>& matrices);
       ^
Comment 2 Daniel Krügler 2012-03-07 18:41:21 UTC
The cause for this problem is the currently unconstrained constructor

template<class InputIter>
vector(InputIter, InputIter);

but I need to investigate whether this is a language or compiler problem. In this case the problem should be fixed, once this constructor becomes constrained (There is work on this in progress, but I have not the bug id right at my hands).
Comment 3 Jonathan Wakely 2012-03-07 18:44:07 UTC
PR 43813

*** This bug has been marked as a duplicate of bug 43813 ***
Comment 4 Dave Steffen 2012-03-07 19:06:56 UTC
(In reply to comment #2)
> The cause for this problem is the currently unconstrained constructor
> 
> template<class InputIter>
> vector(InputIter, InputIter);
> 
> but I need to investigate whether this is a language or compiler problem. In
> this case the problem should be fixed, once this constructor becomes
> constrained (There is work on this in progress, but I have not the bug id right
> at my hands).

Ahhh.... gotcha.  Thanks.  Either way (language or compiler problem) I know how to fix our code.  Looks like an explicit qualification, e.g.

vector<Matrix>{a,b}

makes things happy.


Thanks very much for the fast response time -- you guys are great.
Comment 5 Daniel Krügler 2012-03-08 18:34:36 UTC
(In reply to comment #2)
> but I need to investigate whether this is a language or compiler problem.

It is a language problem. My initial thought that it could be a compiler problem, is invalid (my thanks to Jason for his help here). The following is going on here:

The relevant constructors are:

a) template<class InputIter> vector(InputIter, InputIter);

and simplified (i.e. ignoring default arguments):

b) vector(initializer_list<value_type>);

When considering vector<Matrix>, (b) is the clear winner, but when considering vector<Vector> (b) would not be viable for {a,b}, so the constructor template (a) is tried in the second phase and matches as well. There is no ordering between those two cases, therefore the final ambiguity.