Концепции C ++ 20: Требовать перегрузки оператора - PullRequest
3 голосов
/ 09 июля 2020

Я пытаюсь понять, как объявить концепцию, которая требует определенного оператора, перегружена для данного типа. Допустим, у меня есть следующая функция, которая принимает вектор произвольного типа и печатает его в std::cout:

template<typename printable>
void print_vector(const std::vector<printable>& vec) 
{
  std::cout << '{';
  for (const printable &item : vec) {
    std::cout << item << ',';
  }
  std::cout << '}';
}

Этот код будет работать нормально, если тип printable имеет перегруженный << оператор, но если это не так, то он завершается неудачно с очень бесполезной ошибкой компилятора. Я чувствую, что должен иметь возможность каким-то образом объявить концепцию, которая требует, чтобы тип имел действительный оператор <<, и использовать эту концепцию в объявлении функции, чтобы получить более полезную ошибку компилятора, но я не смог понять, как это сделать.

1 Ответ

5 голосов
/ 09 июля 2020
template <class T>
concept Printable = requires(std::ostream& os, T a)
{
    os << a;
};


template<Printable T>
void print_vector(const std::vector<T>& vec) {
  std::cout << '{';
  for (const auto &item : vec) {
    std::cout << item << ',';
  }
  std::cout << '}';
}

Если вы используете sh, вы также можете сделать его более универсальным c для работы с basic_ostream.

Вот сообщение об ошибке clang:

<source>:30:5: error: no matching function for call to 'print_vector'
    print_vector(x);
    ^~~~~~~~~~~~
<source>:19:6: note: candidate template ignored: constraints not satisfied [with T = X]
void print_vector(std::vector<T> vec) {
     ^
<source>:18:10: note: because 'X' does not satisfy 'Printable'
template<Printable T>
         ^
<source>:10:9: note: because 'os << a' would be invalid: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'X')
    os << a;
       ^

и g cc:

<source>: In function 'auto test()':
<source>:30:19: error: use of function 'void print_vector(std::vector<T>) [with T = X]' with unsatisfied constraints
   30 |     print_vector(x);
      |                   ^
<source>:19:6: note: declared here
   19 | void print_vector(std::vector<T> vec) {
      |      ^~~~~~~~~~~~
<source>:19:6: note: constraints not satisfied
<source>: In instantiation of 'void print_vector(std::vector<T>) [with T = X]':
<source>:30:19:   required from here  
<source>:8:9:   required for the satisfaction of 'Printable<T>' [with T = X]
<source>:8:21:   in requirements with 'std::ostream& os', 'T a' [with T = X]    
<source>:10:9: note: the required expression '(os << a)' is invalid    
   10 |     os << a;
      |     ~~~^~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
...