Ein hübscher Standard Weg, es zu beheben, ist die Klausel std::enable_if
in den Rückgabetyp der Funktion, anstatt in die Vorlage Parameter wie diese.
Dies kompiliert für mich bei C++ 11 Standard.
#include <iostream>
#include <type_traits>
enum class Type {
TypeA,
TypeB,
TypeC
};
class Foo {
public:
template <Type t>
typename std::enable_if<t==Type::TypeA, int>::type get() {
return 1;
}
template <Type t>
typename std::enable_if<t==Type::TypeB, double>::type get() {
return 2;
}
template <Type t>
typename std::enable_if<t==Type::TypeC, float>::type get() {
return 3;
}
};
static_assert(std::is_same<int, decltype(std::declval<Foo>().get<Type::TypeA>())>::value, "");
static_assert(std::is_same<double, decltype(std::declval<Foo>().get<Type::TypeB>())>::value, "");
static_assert(std::is_same<float, decltype(std::declval<Foo>().get<Type::TypeC>())>::value, "");
int main() {
Foo foo;
std::cout << foo.get<Type::TypeA>() << std::endl;
std::cout << foo.get<Type::TypeB>() << std::endl;
std::cout << foo.get<Type::TypeC>() << std::endl;
}
Ich bin mir nicht sicher, ob ich im Detail erklären kann, warum diese Änderung so einen Unterschied für den Compiler macht.
Beachten Sie jedoch Folgendes. Obwohl Sie mit Ihrer Version niemals get
mit zwei expliziten Template-Parametern instanziieren, können technisch alle drei Member-Funktionen-Templates kollidieren und Funktionen mit exakt demselben Namen erzeugen. Denn wenn Sie get<Type::TypeB, int>
instanziiert haben, würde es denselben Rückgabetyp, dieselben Eingabeparameter und denselben Namen haben wie get<Type::TypeA>
. C++ unterstützt keine Funktionsvorlagenspezialisierung, es würde Überladungsauflösungsregeln sehr kompliziert machen. Wenn also Funktionsvorlagen mit dem Potenzial zum Kollidieren vorliegen, kann der Compiler sehr verärgert sein.
Wenn Sie es so machen, wie ich es gezeigt habe, besteht keine Möglichkeit, dass die Vorlagen kollidieren und eine Funktion mit demselben Namen und derselben Signatur erzeugen.
Was ist die Fehlermeldung? Ich denke du kannst das machen. Außerdem steht 'std :: enable_if_t' nicht in' C++ 11'. –
Welcher Compiler ist das? MSVC unterstützt dies noch nicht. – SirGuy