我有一个简单的代码片段,我正在尝试测试数据成员:
#include <type_traits>
template< typename T0 >
using is_data_member = std::bool_constant< std::is_same_v< std::void_t< T0 >, void > >;
template< typename U,
std::add_pointer_t< std::enable_if_t<
is_data_member< decltype( std::declval< U >().a ) >::value
> > = nullptr >
auto test() {}
struct A { int a; };
struct B {};
int main() {
static_assert( is_data_member< decltype( std::declval< A >().a ) >::value );
// #1: static_assert below fails in both gcc and clang.
// static_assert( is_data_member< decltype( std::declval< B >().a ) >::value );
test< A >();
// #2: test< B >() below fails in gcc, but does not fail in clang?
test< B >();
}
使用
gcc
,一切都会按我的预期进行:#1
和#2
的编译错误。但是对于
clang
,只有#1
无法编译,而#2
确实可以编译。请自己看看:code on godbolt。
所以问题是,基本上,这是怎么回事?我倾向于认为
clang
与gcc
相比,与标准的兼容性更好一些,但是在这种情况下,我觉得clang
是错误的吗?谢谢!
最佳答案
这似乎是Clang中的错误。使用当前的Clang干线,替换将按预期失败。
我猜这是通过this bug report解决的,根据该别名模板,如果别名模板的参数(例如is_data_member
)出现在非类型模板参数的类型说明符中,则它们在替换期间未正确处理。
关于c++ - 数据成员SFINAE的C++ 17测试:gcc与clang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60358688/