Я узнал о SFINAE и о том, как легко реализовать его с помощью void_t
. Но я получаю различные результаты для различных компиляторов:Неверный выход для определения члена SFINAE в MSVC2015
//pre c++17 void_t definition:
template<class... Ts> struct make_void {typedef void type;};
template<class... Ts> using void_t = typename make_void<Ts...>::type;
//check for member helper structures
template<class, class = void>
struct has_abc : std::false_type
{ };
template<class T>
struct has_abc<T, void_t<decltype(T::abc)>> : std::true_type
{ };
class has
{
public:
void abc();
};
class has_not
{ };
int main()
{
std::cout << has_abc<has>::value << std::endl;
std::cout << has_abc<has_not>::value << std::endl;
}
GCC 5.3.0 печатает ожидаемый результат 1 0
, но MSVC 2015 печатает 0 0
, почему?
EDIT:
Дополнительный пример с рабочим GCC 5.3.0 код, который предположительно нарушает C++ синтаксис:
template<class T>
void test()
{
std::cout << std::is_same<decltype(T::func), void(T::*)(void)>::value << std::endl;
}
class Test
{
public:
void func();
};
int main()
{
test<Test>();
}
Выход:
1
Просто любопытно, почему бы вам не определить 'void_t' как:' шаблон с использованием void_t = аннулируются; 'В чем проблема с этим? –
Nawaz
@Nawaz Некоторые компиляторы замыкают его на 'void' и избегают всех экземпляров типа. – Barry
@ Барри: Я тоже так думал. Но разве это разрешено спецификацией? Что касается * какой версии * спецификации, это будет интересный вопрос! – Nawaz