Dela via


Kompilatorfel C2668

"function" : tvetydigt anrop till överbelastad funktion

Anmärkningar

Det angivna överlagrade funktionsanropet kunde inte lösas. Du kanske uttryckligen vill omvandla en eller flera av de faktiska parametrarna.

Du kan också få det här felet via mallanvändning. Om du i samma klass har en vanlig medlemsfunktion och en mallad medlemsfunktion med samma signatur måste den mallade komma först. Den här begränsningen finns kvar i den aktuella implementeringen av Visual C++.

Examples

I följande exempel genereras 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 )
}

Ett annat sätt att lösa det här felet är med en 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");
   }
};

Konvertering vid en typkonvertering med konstant 0 är tvetydig eftersom int kräver en konvertering både till long och void*. Lös det här felet genom att omvandla 0 till den exakta typ av funktionsparameter som den används för. Sedan behöver inga konverteringar ske.

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

Det här felet kan inträffa eftersom CRT nu har float och double former för alla matematiska funktioner.

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

Det här felet kan inträffa eftersom har pow(int, int) tagits bort från math.h i CRT.

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

Den här koden lyckas i Visual Studio 2015 men misslyckas i Visual Studio 2017 och senare med C2668. I Visual Studio 2015 behandlade kompilatorn felaktigt kopieringslistans initiering på samma sätt som vanlig kopieringsinitiering. Man övervägde endast att konvertera konstruktorer för överlagringslösning.

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
}