【问题标题】:C++ 20 Concepts: Require operator overloadingC++ 20 概念:要求运算符重载
【发布时间】:2020-07-09 20:40:19
【问题描述】:

我试图了解如何声明一个需要为给定类型重载特定运算符的概念。假设我有以下函数,它接受任意类型的向量并将其打印到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 类型有一个重载的&lt;&lt; 运算符,这段代码就可以正常工作,但如果没有,那么它就会失败并出现一个非常无用的编译器错误。我觉得我应该能够以某种方式声明一个需要定义有效&lt;&lt; 运算符的类型的概念,并在函数声明中使用该概念,这样我可以获得更有用的编译器错误,但我没有能够弄清楚如何做到这一点。

【问题讨论】:

  • 您可以在模板函数中使用static_assert 来检查您的条件(例如
  • @AdrianMaire 根据经验,即使static_assert 失败,编译器也经常会吐出 no match for operatorstatic_assert 可能会产生意想不到的后果(与 SFINAE 或概念相反)。例如,如果 ADL 可以找到另一个 print_vector

标签: c++ c++20 c++-concepts


【解决方案1】:
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 上进行操作。


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

和 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2021-05-02
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多