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

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

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

#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.

所以问题基本上是,发生了什么事?我倾向于认为 clanggcc 相比更符合标准,但在这种情况下,我认为 clang 是错误的?

谢谢!

这似乎是 Clang 中的一个错误。使用当前的 Clang 主干,替换如预期的那样失败。

我猜这是通过 this bug report 解决的,根据别名模板(例如 is_data_member)的参数,如果它们出现在非类型模板的类型说明符中,则在替换期间未被正确处理参数.