【发布时间】:2015-11-01 16:17:01
【问题描述】:
我不明白为什么以下测试在 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;
}
这基本上是 Walter E Brown 在他的 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 错误,还是我做错了什么?
【问题讨论】:
-
你得到什么错误信息?
-
在 VS 中是否已经支持表达式 SFINAE?它未列为可用here:“我们计划在 2015 RTM 之后立即开始在编译器中实现 Expression SFINAE,我们计划在 2015 的更新中提供它,支持生产使用。(但不一定是 2015 Update 1。可能需要更长的时间。)"
-
有趣,感谢您的指点,我会研究一下。 @Alan:我得到的错误是由于 static_assert 失败:main.cpp(143): error C2338: fail,而预期的结果是干净的编译,因为 int 是可复制的。
-
所以经过一番调查,我认为问题不在于表达式 SFINAE。我在第二个示例中使用了
try_assign位,在这种情况下有效。由于 void_t,看起来真的只是一个错误
标签: c++ visual-studio-2015 c++14 sfinae