编译器错误 C2666

更新:2007 年 11 月

错误消息

“identifier”: number 个重载有相似的转换

重载函数或运算符不明确。 形参列表可能太相似,编译器无法解析多义性。 若要消除此错误,请显式强制转换一个或多个实参。

下面的示例生成 C2666:

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

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

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

在 Visual Studio .NET 2003 中所做的编译器一致性工作也可能导致此错误:

  • 二元运算符和用户定义的到指针类型的转换

  • 限定转换不同于标识转换

对于二元运算符 <、>、<= 和 >=,如果传递的参数的类型定义用户定义的转换运算符以转换为操作数的类型,则该参数现在被隐式转换为操作数的类型。现在这可能存在多义性。

有关更多信息,请参见编译时的重大更改摘要。

为使代码在 Visual C++ 的 Visual Studio .NET 2003 和 Visual Studio .NET 版本中均有效,显式使用函数语法调用类运算符。

示例

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

下面的示例生成 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);
    }
};