数据成员SFINAE的C++17测试:gcc vs clang

C++17 testing for data-member SFINAE: gcc vs clang

本文关键字:gcc vs clang 测试 SFINAE C++17 数据成员      更新时间:2023-10-16

我有一个简单的代码片段,我试图在其中测试数据成员:

#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可以编译。请自己看看:godbolt上的代码。

所以问题是,基本上,发生了什么?我倾向于认为,与gcc相比,clang对标准的遵守程度略高,但在这种情况下,我认为clang错了?

谢谢!

这似乎是Clang中的一个错误。根据目前的Clang干线,替换失败,正如预期的那样。

我想这个错误报告解决了这个问题,根据这个错误报告,如果别名模板(如is_data_member(的参数出现在非类型模板参数的类型说明符中,则在替换过程中没有正确处理它们。