erklärt uns auf eine Funktion, die Anwendungen enable_if: mehrdeutig Aufruf
-
19-09-2019 - |
Frage
ich einige Schwierigkeiten haben, uns auf eine Funktion erklärt, dass Verwendungen boost::enable_if
: das folgende Stück Code gibt mir einen Compiler-Fehler:
// Declaration
template <typename T>
void foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
int main()
{
foo(12);
return 0;
}
Beim Kompilieren, ich einen „mehrdeutig Aufruf foo“ Fehler. Nach der Definition von enable_if
, die ‚Typ‘ typedef entspricht void
, wenn die Bedingung erfüllt ist, so weit, wie ich die beiden Unterschriften von foo
Spiel sehen kann. Warum denkt der Compiler sie verschieden sind, und gibt es einen richtigen Weg, um vorwärts declare foo
(vorzugsweise ohne den enable_if
Teil Wiederholung)?
Lösung
Dies ist nicht nur ein Problem mit enable_if. Sie erhalten die gleichen Fehler auf Visual Studio und gcc mit dem folgenden Code:
struct TypeVoid {
typedef void type;
};
template<typename T>
void f();
template<typename T>
typename T::type f() {
}
int main()
{
f<TypeVoid>();
return 0;
}
Ich denke, das Hauptproblem ist, dass der Rückgabetyp (vor Instanziierung) ist Teil der Signatur einer Template-Funktion ist. Es gibt mehr Informationen href="https://stackoverflow.com/questions/290038/is-the-return-type-part-of-the-function-signature">.
Ihr Code angeht, wenn die Erklärung der Definition bezieht, sollten Sie beide übereinstimmen:
// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
Wird die Erklärung auf eine andere Funktion bezieht, würde der Compiler nie in der Lage sein, die richtigen zu wählen, für int s, weil sie beide gültig sind. Sie können jedoch die ersten deaktivieren für int s mit disable_if :
// Other function declaration
template <typename T>
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t);
// Defition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
Andere Tipps
Das Problem ist, dass die Erklärung und die Definition nicht überein.
Die Lösung besteht darin, dass die Erklärung genau die gleiche Signatur enthalten soll, und die die enable_if
Bit.
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
int main()
{
foo(12);
return 0;
}
Dieses compiles fein auf VC2008.