Compilerfehler C2668

'Funktion': mehrdeutiger Aufruf einer überladenen Funktion

Der angegebene überladene Funktionsaufruf konnte nicht aufgelöst werden. Möglicherweise möchten Sie einen oder mehrere der tatsächlichen Parameter explizit casten.

Sie können diesen Fehler auch über die Vorlagennutzung erhalten. Wenn Sie in derselben Klasse über eine reguläre Memberfunktion und eine member-Funktion mit Vorlagen mit derselben Signatur verfügen, muss die vorlagenierte zuerst verwendet werden. Diese Einschränkung bleibt in der aktuellen Implementierung von Visual C++.

Beispiele

Im folgenden Beispiel wird C2668 generiert:

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

Eine andere Möglichkeit, diesen Fehler zu beheben, ist mit einer - using Deklaration:

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

Die Konvertierung für eine Umwandlung mit der Konstante 0 ist mehrdeutig, int da eine Konvertierung sowohl in als long auch in erfordert void*. Um diesen Fehler zu beheben, geben Sie 0 in den genauen Typ des Funktionsparameters um, für den er verwendet wird. Anschließend müssen keine Konvertierungen stattfinden.

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

Dieser Fehler kann auftreten, weil die CRT jetzt float über die Form und double aller mathematischen Funktionen verfügt.

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

Dieser Fehler kann auftreten, weil pow(int, int) aus math.h der CRT entfernt wurde.

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

Dieser Code ist in Visual Studio 2015 erfolgreich, schlägt jedoch Visual Studio 2017 und höher mit C2668 fehl. Im Visual Studio 2015 behandelte der Compiler fälschlicherweise die Kopierlistenin initialisierung auf die gleiche Weise wie die reguläre Kopierin initialisierung. Es wurde nur das Konvertieren von Konstruktoren für die Überladungsauflösung in Betracht gezogen.

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
}