Тестирование C ++ 17 для члена-данных SFINAE: g cc vs clang - PullRequest
1 голос
/ 23 февраля 2020

У меня есть простой фрагмент кода, в котором я пытаюсь проверить элемент данных:

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

Итак, вопрос в основном, что происходит? Я склонен думать, что clang немного лучше соответствует стандарту по сравнению с gcc, но в этом случае мне кажется, что clang не так?

Спасибо!

1 Ответ

1 голос
/ 23 февраля 2020

Это похоже на ошибку в Clang. С текущим соединением Clang замена завершается неудачно, как и ожидалось.

Я думаю, это было решено с помощью этого отчета об ошибке , согласно которому аргументы шаблонов псевдонимов (таких как is_data_member) не обрабатывались правильно во время подстановки, если они появились в спецификаторах типов параметров шаблона нетипичного типа.

...