MSVC incorrectly matching overload's.

Started by
13 comments, last by ApochPiQ 9 years, 9 months ago

Yes, using explicit liberally is the better way to go.

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Advertisement
My bad for confusing you two, i only marked the const char * constructor as explicit at this point.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

I can reproduce the issue with VS2010 such that it appears to be a compiler bug. Would be interested to know if it's fixed in 2012 or 2013 or whether there's something horrendously obscure about C++ overload resolution rules when it comes to ellipsis that actually make this the correct (albeit unexpected) behaviour.

For me, I have two issues with the compiler's behaviour...

Issue 1: Complaining about 2 overloads but only listing one of them in the error. Normally it lists all the options.

This can be reproduced as follows:


struct FromStr
{
    FromStr(const char *) {}
};

void f(const char *, ...) {}
void f(FromStr, const char *) {}

int main()
{
    f("hello", 0);
}

Gives the error:


error C2666: 'f' : 2 overloads have similar conversions
could be 'void f(FromStr,const char *)'
while trying to match the argument list '(const char [6], int)'

Normally it gives the word "or" and lists the other possibilities.

Issue 2: If you introduce a similar 3rd overload, one that should not be a candidate for overload resolution, the error will bizarrely say that now this is the ambiguous signature:


struct FromStr
{
    FromStr(const char *) {}
};

struct FromNothing {};

void f(const char *, ...) {}
void f(FromStr, const char *) {}
void f(FromNothing, const char *) {}

int main()
{
    f("hello", 0);
} 

Gives the error:


error C2666: 'f' : 2 overloads have similar conversions
could be 'void f(FromNothing,const char *)'
while trying to match the argument list '(const char [6], int)'

Which just seems completely bogus to me.

Consequently, I think you do have a signature ambiguity but not the one listed in the error message. Rather, it'll be these two signatures:


QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector2i &Position, const char *Text, ...);
QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector2i &Position, const QWVector4 &DefaultColor, const char *Text, ...);

... because in both cases the 3rd argument can accept the string literal (but the first signature would win that resolution because it's an exact match) whilst the 4th argument can accept a literal 0 (but the second signature would win that resolution because it'll prefer the fixed argument rather than the ellipsis), so it's an ambiguous tie.

In this case, I think marking the constructors as explicit is the right way to go.

Would be interested to know if it's fixed in 2012 or 2013 or whether there's something horrendously obscure about C++ overload resolution rules when it comes to ellipsis that actually make this the correct (albeit unexpected) behaviour.

I have Visual Studio 2013 Ultimate Update 2.

Issue 1


1><..>\source.cpp(11): error C2666: 'f' : 2 overloads have similar conversions
1>          <..>\source.cpp(7): could be 'void f(FromStr,const char *)'
1>          <..>\source.cpp(6): or       'void f(const char *,...)'
1>          while trying to match the argument list '(const char [6], int)'

Issue 2


1><..>\source.cpp(14): error C2666: 'f' : 2 overloads have similar conversions
1>          <..>\source.cpp(10): could be 'void f(FromNothing,const char *)'
1>          <..>\source.cpp(9): or       'void f(FromStr,const char *)'
1>          <..>\source.cpp(8): or       'void f(const char *,...)'
1>          while trying to match the argument list '(const char [6], int)'
C++ does have some wonky rules about overload resolution with the ellipsis construct. I don't remember them well enough offhand to know if they are coming into play here.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement