Вывод аргумента шаблона пользовательского значения (C ++ 2a, P0732R2) - PullRequest
4 голосов
/ 05 мая 2019

Я пытаюсь получить значение параметра шаблона для определяемого пользователем класса (http://wg21.link/p0732r2), с использованием GCC 9.1 с -std = c ++ 2a.

struct user_type {
   int a;
   constexpr user_type( int a ): a( a ){}
};

template< user_type u > struct value {};

template< user_type u > void f( value< u > arg ){}  

void g(){
  f( value< user_type( 0 ) >() ); // error here
}

Проводник компилятора: https://godbolt.org/z/6v_p_R

Я получаю ошибку:

source>:8:30: note:   template argument deduction/substitution failed:
<source>:11:33: note:   couldn't deduce template parameter 'u'
   11 |    f( value< user_type( 0 ) >() );

Я что-то не так делаю? Я ожидал, что такая стоимость будет вычитаться.

Как предложил Никита, я добавил операторы == и! = К типу пользователя, но это не имело значения.

struct user_type {
   int a;
   constexpr user_type( int a ): a( a ){}
   constexpr bool operator==( const user_type & arg ) const {
      return a == arg.a;
   }
   constexpr bool operator!=( const user_type & arg ) const {
      return a != arg.a;
   }
};

1 Ответ

2 голосов
/ 05 мая 2019

Это должно быть плохо сформировано:

struct user_type {
   int a;
   constexpr user_type( int a ): a( a ){}
};

template< user_type u > struct value {};

Для того чтобы быть шаблоном нетипового параметра, вам необходимо удовлетворить [temp.param] / 4 :

Нетипизированный шаблон-параметр должен иметь один из следующих (необязательно квалифицированных cv) типов:

  • литеральный тип, имеющий сильное структурное равенство ([class.compare.default]),
  • [...]

Там, где требуется сильное структурное равенство, с [class.compare.default] / 3 :

Тип C имеет сильное структурное равенство, если при заданном значении x типа const C либо:

  • C является неклассовым типом и [...], или
  • C - это тип класса с оператором ==, определенным как значение по умолчанию в определении C , x == x корректно формируется при контекстном преобразовании в bool, все подобъекты базового класса C и не -статические члены данных имеют сильное структурное равенство, а в C нет изменяемых или изменчивых подобъектов.

Ключ в том, что нам нужно значение по умолчанию == в типе ... и у нас его нет, поэтому у нашего типа нет сильного структурного равенства, поэтому его нельзя использовать как шаблон нетипичного типа. параметр.

Однако gcc не позволяет вам объявить такой оператор, поэтому вы не можете решить проблему.

Это просто неполная реализация новой функции.

...