J'ai le morceau de code suivant :
typedef int AliasB;
typedef unsigned short AliasA;
class Alias
{
public:
explicit Alias(int someInt) { }
};
// (*) !! below breaks the conversion path via AliasA !!
//typedef Alias AliasA;
class C
{
public:
C() { }
};
class B
{
public:
B() { }
B(const AliasB& value) { }
operator AliasB() const
{
return -1000;
}
C combine(const B& someB)
{
return C();
}
};
class A
{
public:
A() { }
operator B() const
{
return B();
}
operator AliasA() const
{
return 1001;
// (*) !! below breaks the conversion path via AliasA !!
//return AliasA(1000);
}
A high()
{
return A();
}
A low()
{
return A();
}
C process()
{
return (static_cast<B>(low())).combine(static_cast<B>(high()));
// (**) !! the below compiles fine !!
//B theB = low();
//return theB.combine(high());
}
};
inline int someFunc(unsigned int someParam, const B& bParam)
{
return 1;
}
inline A createSomeA()
{
return A();
}
int main ()
{
A someA;
unsigned int counter = 200;
someFunc(counter, someA);
//someFunc(counter, static_cast<B>(createSomeA()));
someA.process();
return 0;
}
Clang signale l'erreur suivante :
clang_static_test.cpp:66:17: error: ambiguous conversion for static_cast from 'A' to 'B'
return (static_cast<B>(low())).combine(static_cast<B>(high()));
^~~~~~~~~~~~~~~~~~~~~
clang_static_test.cpp:21:7: note: candidate is the implicit copy constructor
class B
^
clang_static_test.cpp:25:5: note: candidate constructor
B(const AliasB& value) { }
^
clang_static_test.cpp:66:48: error: ambiguous conversion for static_cast from 'A' to 'B'
return (static_cast<B>(low())).combine(static_cast<B>(high()));
^~~~~~~~~~~~~~~~~~~~~~
clang_static_test.cpp:21:7: note: candidate is the implicit copy constructor
class B
^
clang_static_test.cpp:25:5: note: candidate constructor
B(const AliasB& value) { }
^
2 errors generated.
Je n'arrive pas à comprendre pourquoi le compilateur génère une erreur alors que j'ai le fichier soit défini et que je rende la conversion explicite à cet endroit précis en utilisant static_cast<>. Le code passe la compilation avec les compilateurs GCC 4.5.2 et Visual Studio 2008. La version de Clang est la 3.1, construite par moi-même à partir des dépôts git de Clang et LLVM il y a quelques jours.
Clang signale-t-il une erreur réelle ? Et si oui, pourquoi est-ce une erreur car ce n'est pas pas évident pour moi (je ne demanderai pas pourquoi les autres compilateurs sont silencieux à ce sujet) ?
UPDATE : le code d'exemple est maintenant un petit exemple compilable (désolé de ne pas l'avoir fait la première fois) et reproduit la situation réelle que j'ai. Il semble que l'opérateur de conversion vers AliasA soit le problème, car s'il est supprimé, tout se compile correctement. Le problème actuel est que pour le morceau de code ci-dessus, j'obtiens également des erreurs de la part de GCC.
MISE À JOUR 2 : J'ai ajouté du code à l'exemple pour mieux refléter ma situation réelle ; la seule différence est que pour l'exemple ci-dessus, j'obtiens également une erreur de GCC, alors que pour mon code réel, ce n'est pas le cas.