Aracılığıyla paylaş


Derleyici Hatası C2666

'identifier' : sayı aşırı yüklemelerinin benzer dönüştürmeleri vardır

Aşırı yüklenmiş bir işlev veya işleç belirsizdir. Resmi parametre listeleri, derleyicinin belirsizliği çözümlemesi için çok benzer olabilir. Bu hatayı çözmek için, bir veya daha fazla gerçek parametreyi açıkça yayın.

Örnekler

Aşağıdaki örnek C2666 oluşturur:

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

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

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

Bu hata, Visual Studio 2019 sürüm 16.1 için yapılan derleyici uyumluluğu çalışmasının bir sonucu olarak oluşturulabilir:

  • Temel türü temel alınan türüne sabitlenmiş bir numaralandırmayı yükselten dönüştürme, ikisi farklıysa yükseltilen temel türe yükselten bir dönüştürmeden daha iyidir.

Aşağıdaki örnek, Visual Studio 2019 sürüm 16.1 ve sonraki sürümlerde derleyici davranışının nasıl değiştiğini gösterir:

#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{});
}

Bu hata, Visual Studio .NET 2003 için yapılan derleyici uyumluluğu çalışmasının bir sonucu olarak da oluşturulabilir:

  • ikili işleçler ve işaretçi türlerine kullanıcı tanımlı dönüştürmeler

  • nitelik dönüştürme, kimlik dönüştürme ile aynı değildir

, = ><ve >= ikili işleçleri <için, parametrenin türü işlenenin türüne dönüştürülecek kullanıcı tanımlı bir dönüştürme işleci tanımlıyorsa geçirilen bir parametre örtük olarak işlenen türüne dönüştürülür. Artık belirsizlik olasılığı vardır.

Visual C++'ın hem Visual Studio .NET 2003 hem de Visual Studio .NET sürümlerinde geçerli olan kodlar için, işlev söz dizimini kullanarak sınıf işlecini açıkça çağırın.

// 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");
}

Aşağıdaki örnek C2666 oluşturur

// 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);
    }
};