sfinae проверяет статический член, используя decltype
Я написал код ниже, чтобы попытаться определить, имеет ли тип статическую переменную-член. К сожалению, всегда возвращается, что переменная не существует.
Может кто-нибудь сказать мне, где я иду не так? Я использую g++ 4.7.1.
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
template <class T>
class has_is_baz
{
template<class U,
typename std::enable_if<std::is_same<bool, decltype(U::is_baz)>::value>::type...>
static std::true_type check(int);
template <class>
static std::false_type check(...);
public:
static constexpr bool value = decltype(check<T>(0))::value;
};
struct foo { };
struct bar
{
static constexpr bool is_baz = true;
};
int main()
{
cout << has_is_baz<foo>::value << '\n';
cout << has_is_baz<bar>::value << '\n';
}
2 ответа
Решение
Основная проблема заключалась в том, что:
std::is_same<bool, decltype(bar::is_baz)>::value == false
Тогда твоя СФИНАЭ всегда терпела неудачу. Я переписал has_is_baz
черта, и это теперь работает:
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
template <class T>
class has_is_baz
{
template<class U, class = typename std::enable_if<!std::is_member_pointer<decltype(&U::is_baz)>::value>::type>
static std::true_type check(int);
template <class>
static std::false_type check(...);
public:
static constexpr bool value = decltype(check<T>(0))::value;
};
struct foo { };
struct bar
{
static constexpr bool is_baz = true;
};
struct not_static {
bool is_baz;
};
int main()
{
cout << has_is_baz<foo>::value << '\n';
cout << has_is_baz<bar>::value << '\n';
cout << has_is_baz<not_static>::value << '\n';
}
Демо здесь.
Изменить: я исправил черту типа. Как указывало @litb, он обнаруживал как статические, так и нестатические элементы.
Проблема в вашем коде в том, что constexpr
объект неявно const
, что означает, что ваш тест для того же типа должен быть:
std::is_same<const bool, decltype(U::is_baz)>::value
Это указано в стандарте в §7.1.5 [dcl.constexpr]/9.
Спецификатор constexpr, используемый в объявлении объекта, объявляет объект как const. [...]