Sdílet prostřednictvím


Chyba kompilátoru C2666

'identifier' : přetížení čísel mají podobné převody

Přetížená funkce nebo operátor je nejednoznačný. Formální seznamy parametrů můžou být příliš podobné, aby kompilátor přeložil nejednoznačnost. Pokud chcete tuto chybu vyřešit, explicitně přetypujte jeden nebo více skutečných parametrů.

Příklady

Následující ukázka vygeneruje C2666:

// C2666.cpp
struct complex {
   complex(double);
};

void h(int,complex);
void h(double, double);

int main() {
   h(3,4);   // C2666
}

Tato chyba se dá vygenerovat v důsledku práce kompilátoru, která byla provedena pro Visual Studio 2019 verze 16.1:

  • Převod, který propaguje výčet, jehož základní typ je pevně nastaven na jeho základní typ, je lepší než ten, který podporuje upřednostněný základní typ, pokud se oba typy liší.

Následující příklad ukazuje změny chování kompilátoru v sadě Visual Studio 2019 verze 16.1 a novějších verzích:

#include <type_traits>

enum E : unsigned char { e };

int f(unsigned int)
{
    return 1;
}

int f(unsigned char)
{
    return 2;
}

struct A {};
struct B : public A {};

int f(unsigned int, const B&)
{
    return 3;
}

int f(unsigned char, const A&)
{
    return 4;
}

int main()
{
    // Calls f(unsigned char) in 16.1 and later. Called f(unsigned int) in earlier versions.
    // The conversion from 'E' to the fixed underlying type 'unsigned char' is better than the
    // conversion from 'E' to the promoted type 'unsigned int'.
    f(e);
  
    // Error C2666. This call is ambiguous, but previously called f(unsigned int, const B&). 
    f(e, B{});
}

Tuto chybu lze také vygenerovat v důsledku práce kompilátoru, která byla provedena pro Visual Studio .NET 2003:

  • binární operátory a uživatelem definované převody na typy ukazatelů

  • převod kvalifikace není stejný jako převod identity.

Pro binární operátory <, = <>a >=, předaný parametr je nyní implicitně převeden na typ operandu, pokud typ parametru definuje uživatelem definovaný operátor převodu pro převod na typ operandu. Existuje teď potenciál nejednoznačnosti.

Pro kód, který je platný v sadě Visual Studio .NET 2003 i ve verzích Visual C++ sady Visual Studio .NET++, zavolejte operátor třídy explicitně pomocí syntaxe funkce.

// C2666b.cpp
#include <string.h>
#include <stdio.h>

struct T
{
    T( const T& copy )
    {
        m_str = copy.m_str;
    }

    T( const char* str )
    {
        int iSize = (strlen( str )+ 1);
        m_str = new char[ iSize ];
        if (m_str)
            strcpy_s( m_str, iSize, str );
    }

    bool operator<( const T& RHS )
    {
        return m_str < RHS.m_str;
    }

    operator char*() const
    {
        return m_str;
    }

    char* m_str;
};

int main()
{
    T str1( "ABCD" );
    const char* str2 = "DEFG";

    // Error - Ambiguous call to operator<()
    // Trying to convert str1 to char* and then call
    // operator<( const char*, const char* )?
    //  OR
    // trying to convert str2 to T and then call
    // T::operator<( const T& )?

    if( str1 < str2 )   // C2666

    if ( str1.operator < ( str2 ) )   // Treat str2 as type T
        printf_s("str1.operator < ( str2 )\n");

    if ( str1.operator char*() < str2 )   // Treat str1 as type char*
        printf_s("str1.operator char*() < str2\n");
}

Následující ukázka vygeneruje C2666.

// C2666c.cpp
// compile with: /c

enum E
{
    E_A,   E_B
};

class A
{
    int h(const E e) const {return 0; }
    int h(const int i) { return 1; }
    // Uncomment the following line to resolve.
    // int h(const E e) { return 0; }

    void Test()
    {
        h(E_A);   // C2666
        h((const int) E_A);
        h((int) E_A);
    }
};