Ich habe vor kurzem versucht, eine sfinae Typ Merkmal zu erkennen, ob eine Klasse eine bestimmte Vorlage statische Funktion namens construct
enthält.Sfinae Typ Merkmal zu Template-Funktion zu erkennen funktioniert nicht mit Std :: vorwärts
Ich kam mit dieser Implementierung:
template<typename T, typename... Args>
struct has_template_construct_helper {
private:
template<typename U, typename... As>
static std::true_type test(decltype(&U::template construct<As...>)*);
template<typename...>
static std::false_type test(...);
public:
using type = decltype(test<T, Args...>(nullptr));
};
template<typename T, typename... Args>
using has_template_construct = typename has_template_construct_helper<T, Args...>::type;
ich tought das in Ordnung wäre, und es war. Ich habe versucht, meine Eigenschaft mit gcc und clang wie folgt zu testen:
struct TestStruct {
template<typename... Args>
static auto construct(int a, double b, Args... args) -> decltype(std::make_tuple(a, b, args...)) {
return std::make_tuple(1, 2.3, std::forward<Args>(args)...);
}
};
// didn't fire! Hurrah!
static_assert(has_template_construct<TestStruct, std::string>::value, "Don't pass the test");
Es funktionierte für beide Compiler.
aber sobald ich Spedition Referenzen hinzufügen, beginnt Klirren klagen:
struct TestStruct {
template<typename... Args>
static auto construct(int a, double b, Args&&... args) -> decltype(std::make_tuple(a, b, std::forward<Args>(args)...))
{
return std::make_tuple(1, 2.3, std::forward<Args>(args)...);
}
};
// fires on clang :(
static_assert(has_template_construct<TestStruct, std::string>::value, "Don't pass the test");
Hier ist der Code-Snippet auf coliru: GCC, Clang
Meine Frage ist: die man zwischen GCC und Clang ist falsch, und wie kann ich meinen Code reparieren, damit es auf beiden Compiler funktioniert?
Okay, ich habe Dinge versucht, jetzt bin ich noch mehr verwirrt. Bei der Verwendung von std::declval
funktionierte es in clang!
Kommentieren Sie 'test (...)' und sehen Sie, was der tatsächliche Fehler während der Substitution ist. Das wird helfen. – skypjack
Was bedeutet "funktioniert nicht mit std :: forward"? Es gibt keinen Typ, den Sie std :: forward nicht mit bekannten Ergebnissen zur Kompilierung aufrufen können. – xaxxon
Ich denke, es ist ein Bug im Klang. Das Hinzufügen einer Weiterleitungsreferenz führt zu der Annahme, dass für die Konstruktmethode eine Überladung vorliegt, und daher wird der Fehler verworfen. – Arunmu