Я не понимаю, почему следующий тест всегда терпит неудачу с Visual Studio 2015 (триггеры static_assert):
#include <type_traits>
using namespace std;
template<class T> using try_assign = decltype(declval<T&>() = declval<T const&>());
template<class, class = void> struct my_is_copy_assignable : false_type {};
template<class T> struct my_is_copy_assignable<T, void_t<try_assign<T>>> : true_type {};
int main()
{
static_assert(my_is_copy_assignable<int>::value, "fail");
return 0;
}
Это в основном транскрипция примера использования Уолтера E Брауна void_t из его презентации cppcon 2014 "Современное метапрограммирование шаблона - сборник".
Важно отметить, что эта альтернативная версия работает, поэтому я не думаю, что проблема заключается в неполной поддержке MSVC для выражения SFINAE.
template<class T>
using try_assign = decltype(declval<T&>() = declval<T const&>());
template<class T>
struct my_is_copy_assignable
{
template<class Q, class = try_assign<Q>>
static true_type tester(Q&&);
static false_type tester(...);
using type = decltype(tester(declval<T>()));
};
Я знаю о std::is_copy_assignable
, но мне просто интересно понять различные методы метапрограммирования, доступные в разных версиях С++. Я прочитал несколько потоков о void_t в Интернете, но я до сих пор не понимаю, почему этот пример терпит неудачу.
Интересно, что с GCC 4.8.2 он отлично работает (с использованием обходного решения CWG 1558, которое совпадает с версией Microsoft).
Является ли это известной ошибкой Visual Studio, или я делаю что-то неправильно?