Poniższy kod poprawnie sprawdza, czy typ T
ma metodę sort
. Ale kiedy modyfikuję linię oznaczoną (*)
zmieniając decltype(&U::sort,...)
na decltype(U::sort,...)
(usunięto symbol &
), kod zawsze zwraca false
.SFINAE ze znakami ampersand przed funkcją o nazwie
Dlaczego?
Dlaczego sama nazwa nie jest wystarczająca? Co to oznacza &
?
#include <iostream>
#include <type_traits>
template <typename T>
class has_sort {
template <typename U>
static auto check(bool) -> decltype(&U::sort, std::true_type()); // (*)
template <typename U>
static std::false_type check(...);
public:
using type = decltype(check<T>(true));
static bool const value = type::value;
};
int main() {
struct Foo { void sort(); };
struct Foo2 { void sort2(); };
std::cout << "Foo: " << has_sort<Foo>::value << std::endl;
std::cout << "Foo2: " << has_sort<Foo2>::value << std::endl;
std::cout << "int: " << has_sort<int>::value << std::endl;
}
Szkoda, że nie mogę zaakceptować dwóch odpowiedzi. Nawiasem mówiąc, wersja bez ampersandów pasuje nie tylko do elementu danych (statycznego lub nie), ale także do statycznej metody. – olpa
clang też to akceptuje i myślę, że jest poprawna. Standard mówi: "Statyczna funkcja członka (9.4) jest zwykłą funkcją." – olpa
Rzeczywiście, sprawdzanie może być poprawne bez ampersand dla funkcji statycznych, ale jest wymagane dla niestatycznych funkcji składowych. –