我不理解为什么以下测试在使用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·布朗在他的cppcon 2014演讲“现代模板元编程 - 概览”中对void_t示例用法的转录。
需要注意的是,这个替代版本可以工作,因此我认为问题不在于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
,但我对于C++不同版本中可用的各种元编程技术更好的理解感兴趣。我在网上阅读了几个关于 void_t 的帖子,但我仍然不明白为什么这个例子失败了。有趣的是,在 GCC 4.8.2 中它可以正常工作(使用 CWG 1558 解决方法,这与 Microsoft 版本相同)。
这是一个已知的 Visual Studio bug,还是我做错了什么?
try_assign
位,在那种情况下它可以工作。看起来只是由于void_t引起的一个错误。 - Federico Sauro