C++20概念:需要运算符重载

C++ 20 Concepts: Require operator overloading

本文关键字:运算符 重载 概念 C++20      更新时间:2023-10-16

我正在努力理解如何声明一个概念,该概念要求特定运算符对给定类型重载。假设我有以下函数,它获取任意类型的向量并将其打印到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具有重载的<<运算符,则此代码将正常工作,但如果没有,则它将失败,并出现一个非常无用的编译器错误。我觉得我应该能够以某种方式声明一个概念,这个概念需要一个定义了有效<<运算符的类型,并在函数声明中使用这个概念,这样我就可以得到一个更有用的编译器错误,但我还不知道如何做

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 << '}';
}

如果您希望的话,还可以使其更通用地操作basic_ostream


这是叮当声错误消息:

<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;
^

和gcc:

<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