Sign in to follow this  

MSVC incorrectly matching overload's.

This topic is 1270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hey folks, i'm having an issue with with function overloading of variable arguments in c++ on msvc.

 

i get the following error:

error C2666: 'QWFont::DrawTextf' : 2 overloads have similar conversions
1>          c:\users\admin_tc\projects\qwengine\includes\qwfont.h(293): could be 'QWVector2i QWFont::DrawTextf(QWBaseMesh *,const QWVector4 &,const QWVector2i &,const char *,...)'
1>          while trying to match the argument list '(QWMesh<VertexType> *, QWVector2i, const char [17], int)'
1>          with
1>          [
1>              VertexType=QWVertex_UI
1>          ]
1>
 
first of all, it only tells me the first of the two options it want's to match, so i'm pretty much assuming the other method is the one i want.
 
the correct method that i'm trying to get is declared like so:
QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector2i &Position, const char *Text, ...);
 
and the incorrect method like:
QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector4 &ClipPlane, const QWVector2i &Position, const char *Text, ...);
 
i'm calling the method like so:
Font->DrawTextf(UIMesh, QWVector2i(0, Font->GetDefaultGlyphTable()->GetMaxHeight()), "Mode: Shape - %d", 0)
 
what i don't understand is to make this work the compiler is trying to force the second parameter to become a QWVector4, which is not possible.  i have no functions to convert between the two, so i'm unsure why the compiler is thinking QWVector2i can satisfy QWVector4 parameter.
 
thanks for the answers.

Share this post


Link to post
Share on other sites

Does QWVector4 have some way of being constructed directly from a QWVector2i?

 

Negative.  I have an function in QWVector2i that can return a QWVector4, but i don't think the compiler would use that.

 

You may need to post code for the call site, along with relevant declarations. Are you sure that's the complete error text?

 

yes, that's the complete error that i get.  also not sure what else is needed from the call site, as for relevant declarations these are all the possible overloads:

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

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

    QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector2i &Position, const QWVector4 &DefaultColor, QWGlyphTable *DefaultGlyph, const char *Text, ...);
    
    QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector2i &Position, const QWVector4 &DefaultColor, QWGlyphTable *DefaultGlyph, const char *Text, unsigned int Length, va_list lst);

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

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

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

    QWVector2i DrawTextf(QWBaseMesh *Mesh, const QWVector4 &ClipPlane, const QWVector2i &Position, const QWVector4 &DefaultColor, QWGlyphTable *DefaultGlyph, const char *Text, unsigned int Length, va_list lst);

these are my vector classes:

QWVector2:

struct QWVector2i{
public:
    int x, y;

    void Set(int fx, int fy);

    float Distance(const QWVector2i &Vec);

    float DistanceSquared(const QWVector2i &Vec);

    int Dot(const QWVector2i &Vec);

    QWVector2i Perpendicular();

    void Perpendicular(QWVector2i &Result);

    bool Is(int Value);
  
    QWVector4 ToVector4(void) const;

    QWVector4 ToVector4(unsigned char Flag) const;

    void ToVector4(QWVector4 &Result) const;

    void ToVector4(QWVector4 &Result, unsigned char Flag) const;
 
    QWVector4i ToVector4i(void) const;

    QWVector4i ToVector4i(unsigned char Flag) const;

    void ToVector4i(QWVector4i &Result) const;

    void ToVector4i(QWVector4i &Result, unsigned char Flag) const;

    QWVector3 ToVector3(void) const;

    QWVector3 ToVector3(unsigned char Flag) const;

    void ToVector3(QWVector3 &Result) const;

    void ToVector3(QWVector3 &Result, unsigned char Flag) const;

    QWVector3i ToVector3i(void) const;

    QWVector3i ToVector3i(unsigned char Flag) const;

    void ToVector3i(QWVector3i &Result) const;

    void ToVector3i(QWVector3i &Result, unsigned char Flag) const;

    QWVector2 ToVector2(void) const;

    QWVector2 ToVector2(unsigned char Flag) const;

    void ToVector2(QWVector2 &Result) const;

    void ToVector2(QWVector2 &Result, unsigned char Flag) const;

    char *ToString(char *Buffer, unsigned int BufferSize);

    unsigned int FromString(const char *Text);

    QWVector2i &operator = (const QWVector2i &Rhs);

    QWVector2i &operator += (const QWVector2i &Rhs);

    QWVector2i &operator += (int Rhs);

    QWVector2i &operator -= (const QWVector2i &Rhs);

    QWVector2i &operator -= (int Rhs);

    QWVector2i &operator *= (const QWVector2i &Rhs);

    QWVector2i &operator *= (int Rhs);

    QWVector2i &operator /= (const QWVector2i &Rhs);

    QWVector2i &operator /= (int Rhs);

    friend QWVector2i operator + (const QWVector2i &Rhs);

    friend QWVector2i operator - (const QWVector2i &Rhs);

    unsigned char operator == (const QWVector2i &Rhs);

    unsigned char operator != (const QWVector2i &Rhs);

    friend QWVector2i operator + (const QWVector2i &Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator + (const QWVector2i &Lhs, int Rhs);

    friend QWVector2i operator + (int Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator - (const QWVector2i &Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator - (const QWVector2i &Lhs, int Rhs);

    friend QWVector2i operator - (int Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator * (const QWVector2i &Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator * (const QWVector2i &Lhs, int Rhs);

    friend QWVector2i operator * (int Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator / (const QWVector2i &Lhs, const QWVector2i &Rhs);

    friend QWVector2i operator / (const QWVector2i &Lhs, int Rhs);

    friend QWVector2i operator / (int Lhs, const QWVector2i &Rhs);

    QWVector2i(const char *Text);

    QWVector2i(const QWVector2i &O);

    QWVector2i(int x, int y);

    QWVector2i(int *Xy);

    QWVector2i(int f=0);
};

QWVector4:

struct QWVector4{
    float x, y, z, w;

    void Set(float fx, float fy, float fz, float fw);

    QWVector4 Normalize(void);

    void Normalize(QWVector4 &Result);

    float Length(void);

    float LengthSquared(void);

    float Distance(const QWVector4 &Vec);

    float DistanceSquared(const QWVector4 &Vec);

    float Dot(const QWVector4 &Vec);

    bool Is(float Value);

    bool IsUnit(void);

    char *ToString(char *Buffer, unsigned int BufferSize, unsigned int Precision=4);

    unsigned int FromString(const char *Text);

    QWVector4i ToVector4i(void) const;

    QWVector4i ToVector4i(unsigned char Flag) const;

    void ToVector4i(QWVector4i &Result) const;

    void ToVector4i(QWVector4i &Result, unsigned char Flag) const;

    QWVector3 ToVector3(void) const;

    QWVector3 ToVector3(unsigned char Flag) const;

    void ToVector3(QWVector3 &Result) const;

    void ToVector3(QWVector3 &Result, unsigned char Flag) const;

    QWVector3i ToVector3i(void) const;

    QWVector3i ToVector3i(unsigned char Flag) const;

    void ToVector3i(QWVector3i &Result) const;

    void ToVector3i(QWVector3i &Result, unsigned char Flag) const;

    QWVector2 ToVector2(void) const;

    QWVector2 ToVector2(unsigned char Flag) const;

    void ToVector2(QWVector2 &Result) const;

    void ToVector2(QWVector2 &Result, unsigned char Flag) const;

    QWVector2i ToVector2i(void) const;

    QWVector2i ToVector2i(unsigned char Flag) const;

    void ToVector2i(QWVector2i &Result) const;

    void ToVector2i(QWVector2i &Result, unsigned char Flag) const;

    QWVector4 &operator = (const QWVector4 &Rhs);

    QWVector4 &operator += (const QWVector4 &Rhs);

    QWVector4 &operator += (float Rhs);

    QWVector4 &operator -= (const QWVector4 &Rhs);

    QWVector4 &operator -= (float Rhs);

    QWVector4 &operator *= (const QWVector4 &Rhs);

    QWVector4 &operator *= (float Rhs);

    QWVector4 &operator /= (const QWVector4 &Rhs);

    QWVector4 &operator /= (float Rhs);

    friend QWVector4 operator + (const QWVector4 &Rhs);

    friend QWVector4 operator - (const QWVector4 &Rhs);

    unsigned char operator == (const QWVector4 &Rhs);

    unsigned char operator != (const QWVector4 &Rhs);

    friend QWVector4 operator + (const QWVector4 &Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator + (const QWVector4 &Lhs, float Rhs);

    friend QWVector4 operator + (float Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator - (const QWVector4 &Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator - (const QWVector4 &Lhs, float Rhs);

    friend QWVector4 operator - (float Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator * (const QWVector4 &Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator * (const QWVector4 &Lhs, float Rhs);

    friend QWVector4 operator * (float Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator / (const QWVector4 &Lhs, const QWVector4 &Rhs);

    friend QWVector4 operator / (const QWVector4 &Lhs, float Rhs);

    friend QWVector4 operator / (float Lhs, const QWVector4 &Rhs);

    QWVector4(const char *Text);

    QWVector4(const QWVector4 &O);

    QWVector4(const QWVector2 &Xy, const QWVector2 &Zw);

    QWVector4(float x, const QWVector3 &Yzw);

    QWVector4(float x, float y, const QWVector2 &Zw);

    QWVector4(const QWVector3 &Xyz, float w);

    QWVector4(const QWVector2 &Xy, float z, float w);

    QWVector4(float x, float y, float z, float w);

    QWVector4(float *Xyzw);

    QWVector4(float f=0.0f);
};

My initial thought is that:

 

a) A QWVector4 may be implicitly constructable or castable from a QWVector2i

b) A QWVector2i may be implicitly constructable or castable from a const char [17]

 

A. negative.

B. i do have such a function, but removing it doesn't fix the issue.

Edited by slicer4ever

Share this post


Link to post
Share on other sites

Does marking the constructors as explicit help at all?
 
I would also try to reduce the number of factors at play and reproduce the issue on a smaller scale. One specific wondering is whether the varargs have anything to do with it.

yes, by marking all the QWVector4 constructors as explicit, it fixed the issue.  i'll investigate to try and find the one doing this.

 

edit: it appears to come from an explicit conversion of the const char * version, but i'm still unsure why it matches that.

Edited by slicer4ever

Share this post


Link to post
Share on other sites

it appears to come from an explicit conversion of the const char * version, but i'm still unsure why it matches that.

 
Can a QWVector2i be implicitly cast into a string/char* ?
If so, it might be teaming up with the QWVector4(const char *Text) constructor to permit a conversion.

 

If you can just instantiate something like the following, then you should be able to step though with a debugger and see how it's happening:

 

QWVector4 foo(QWVector2i());

Share this post


Link to post
Share on other sites

 

it appears to come from an explicit conversion of the const char * version, but i'm still unsure why it matches that.

 

QWVector4 foo(QWVector2i());

 

 

Negative i get: error C2664: 'QWVector4::QWVector4(const char *)' : cannot convert parameter 1 from 'QWVector2i' to 'const char *'

Share this post


Link to post
Share on other sites

No need to make all of them explicit, though as a rule of thumb, I'd always make any constructor explicit that takes exactly one parameter, unless I want it to be used behind my back for implicit casts (one has to wonder why explicit isn't the default and implicit is the optional keyword).

Share this post


Link to post
Share on other sites
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)'
Edited by Zaoshi Kaba

Share this post


Link to post
Share on other sites

This topic is 1270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this