Warum verursacht der folgende Code einen Fehler? Ich würde denken, dass der Compiler hier einfach die entsprechende Überladung auswählt?Fehler mit SFINAE
#include <iostream>
using std::cout;
using std::endl;
template <typename ToCheckFor>
struct InterfaceCheck {
// used by the constexpr function, the function will pass in a pointer to
// a type with the required types
template <typename _ToCheckFor, void (_ToCheckFor::*)()>
struct InterfaceCheckImplTag {};
// used to check for the presence of a function print()
// template <typename T>
// static constexpr bool function(__attribute__((unused)) void* ptr) {}
template <typename T>
static constexpr bool function(__attribute__((unused)) void* ptr) {
return false;
}
template <typename T>
static constexpr bool function (__attribute__((unused))
InterfaceCheckImplTag<T, &T::print>* ptr) {
return true;
}
constexpr static const bool value = function<ToCheckFor>(nullptr);
};
struct Something {
void print() { cout << "Something::print()" << endl; }
};
int main() {
cout << InterfaceCheck<Something>::value << endl;
return 0;
}
Warum ersetzt das void*
Argument mit einem Auslassungs den Code funktioniert wie erwartet? So funktioniert der folgende Code als
#include <iostream>
using std::cout;
using std::endl;
template <typename ToCheckFor>
struct InterfaceCheck {
// used by the constexpr function, the function will pass in a pointer to
// a type with the required types
template <typename _ToCheckFor, void (_ToCheckFor::*)()>
struct InterfaceCheckImplTag {};
// used to check for the presence of a function print()
// template <typename T>
// static constexpr bool function(__attribute__((unused)) void* ptr) {}
template <typename T>
static constexpr bool function(...) {
return false;
}
template <typename T>
static constexpr bool function (__attribute__((unused))
InterfaceCheckImplTag<T, &T::print>* ptr) {
return true;
}
constexpr static const bool value = function<ToCheckFor>(nullptr);
};
struct Something {
void print() { cout << "Something::print()" << endl; }
};
int main() {
cout << InterfaceCheck<Something>::value << endl;
return 0;
}
Schön! Gibt es noch etwas über "..." das ich wissen sollte? Wie wo es benutzt wird? – Curious
Ich benutze es nie außer in Meta-Programmen wie dem in Ihrer Frage. Es kann zur Laufzeit verwendet werden. Ich habe keinen Nutzen dafür. Ich werde stattdessen variadische Vorlagen verwenden (was auch die Ellipsis-Syntax beinhaltet, aber nicht dasselbe ist). –