Erro do compilador C2668

'function': chamada ambígua à função sobrecarregada

A chamada de função sobrecarregada especificada não pôde ser resolvida. Talvez você queira converter explicitamente um ou mais dos parâmetros reais.

Você também pode obter esse erro por meio do uso do modelo. Se, na mesma classe, você tiver uma função de membro regular e uma função de membro com modelo com a mesma assinatura, a função com modelo deverá vir primeiro. Essa limitação permanece na implementação atual do Visual C++.

Exemplos

A amostra a seguir gera o erro C2668:

// C2668.cpp
struct A {};
struct B : A {};
struct X {};
struct D : B, X {};

void func( X, X ){}
void func( A, B ){}
D d;
int main() {
   func( d, d );   // C2668 D has an A, B, and X
   func( (X)d, (X)d );   // OK, uses func( X, X )
}

Outra maneira de resolver esse erro é com uma using declaração:

// C2668b.cpp
// compile with: /EHsc /c
// C2668 expected
#include <iostream>
class TypeA {
public:
   TypeA(int value) {}
};

class TypeB {
   TypeB(int intValue);
   TypeB(double dbValue);
};

class TestCase {
public:
   void AssertEqual(long expected, long actual, std::string
                    conditionExpression = "");
};

class AppTestCase : public TestCase {
public:
   // Uncomment the following line to resolve.
   // using TestCase::AssertEqual;
   void AssertEqual(const TypeA expected, const TypeA actual,
                    std::string conditionExpression = "");
   void AssertEqual(const TypeB expected, const TypeB actual,
                    std::string conditionExpression = "");
};

class MyTestCase : public AppTestCase {
   void TestSomething() {
      int actual = 0;
      AssertEqual(0, actual, "Value");
   }
};

A transformação em uma conversão usando a constante 0 é ambígua, pois int requer uma conversão para long e para void*. Para resolver esse erro, converta 0 para o tipo exato do parâmetro de função para o qual ele está sendo usado. Em seguida, nenhuma conversão precisa ocorrer.

// C2668c.cpp
#include "stdio.h"
void f(long) {
   printf_s("in f(long)\n");
}
void f(void*) {
   printf_s("in f(void*)\n");
}
int main() {
   f((int)0);   // C2668

   // OK
   f((long)0);
   f((void*)0);
}

Esse erro pode ocorrer porque o CRT agora tem as formas float e double de todas as funções matemáticas.

// C2668d.cpp
#include <math.h>
int main() {
   int i = 0;
   float f;
   f = cos(i);   // C2668
   f = cos((float)i);   // OK
}

Esse erro pode ocorrer porque pow(int, int) foi removido de math.h no CRT.

// C2668e.cpp
#include <math.h>
int main() {
   pow(9,9);   // C2668
   pow((double)9,9);   // OK
}

Esse código é bem-sucedido no Visual Studio 2015, mas falha no Visual Studio 2017 e posterior com o C2668. No Visual Studio 2015, o compilador tratou a inicialização de lista de cópia de maneira incorreta da mesma maneira de uma inicialização de cópia regular. Ele considerou somente a conversão de construtores para a resolução de sobrecarga.

struct A {
    explicit A(int) {}
};

struct B {
    B(int) {}
};

void f(const A&) {}
void f(const B&) {}

int main()
{
    f({ 1 }); // error C2668: 'f': ambiguous call to overloaded function
}