I don't understand why the following test always fails with Visual Studio 2015 (the static_assert triggers):
#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;
}
It's basically the transcription of Walter E Brown's example usage of void_t from his cppcon 2014 presentation "Modern Template Metaprogramming - A compendium".
It's important to note that this alternate version works so I don't think that the problem lies in MSVC's incomplete support to expression 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>()));
};
I know about std::is_copy_assignable
but I'm just interested in better understanding the various metaprogramming techniques available in the different revisions of C++. I read several threads about void_t on the web but I still don't understand why this example fails.
The interesting thing is that with GCC 4.8.2 it works fine (using the CWG 1558 workaround, which is the same that the Microsoft's version does).
Is it a known Visual Studio bug, or am I doing something wrong?