MSVC incorrectly matching overload's.

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

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.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.
Advertisement
Does QWVector4 have some way of being constructed directly from a QWVector2i?

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

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

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]

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.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

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.

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.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

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());

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 *'

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

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).

f@dzhttp://festini.device-zero.de

This topic is closed to new replies.

Advertisement