Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
'id' : overbelasting van getallen heeft vergelijkbare conversies
Opmerkingen
Een overbelaste functie of operator is dubbelzinnig. Formele parameterlijsten kunnen te vergelijkbaar zijn voor de compiler om de dubbelzinnigheid op te lossen. U kunt deze fout oplossen door expliciet een of meer van de werkelijke parameters te casten.
Voorbeelden
In het volgende voorbeeld wordt C2666 gegenereerd:
// C2666.cpp
struct complex {
complex(double);
};
void h(int,complex);
void h(double, double);
int main() {
h(3,4); // C2666
}
Deze fout kan worden gegenereerd als gevolg van het conformance-werk van de compiler dat is uitgevoerd voor Visual Studio 2019 versie 16.1:
- Een conversie die een opsomming bevordert waarvan het onderliggende type is vastgezet aan het onderliggende type, is beter dan een conversie die het gepromoveerde onderliggende type bevordert, als de twee verschillend zijn.
In het volgende voorbeeld ziet u hoe het gedrag van compileren verandert in Visual Studio 2019 versie 16.1 en nieuwere versies:
#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{});
}
Deze fout kan ook worden gegenereerd als gevolg van het conforme compilerwerk dat is uitgevoerd voor Visual Studio .NET 2003:
binaire operatoren en door de gebruiker gedefinieerde conversies naar aanwijzertypen
kwalificatieconversie is niet hetzelfde als identiteitsconversie
Voor de binaire operatoren<, ><=en >=, wordt een doorgegeven parameter nu impliciet geconverteerd naar het type operand als het type van de parameter een door de gebruiker gedefinieerde conversieoperator definieert om te converteren naar het type operand. Er is nu sprake van dubbelzinnigheid.
Voor code die geldig is in zowel de .NET 2003- als visual Studio .NET-versies van Visual C++, roept u de klasseoperator expliciet aan met behulp van de functiesyntaxis.
// 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");
}
In het volgende voorbeeld wordt C2666 gegenereerd
// 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);
}
};