【问题标题】:Recursive spaceship operator递归宇宙飞船算子
【发布时间】:2021-07-27 01:21:50
【问题描述】:

我已经写了这个简单的代码,但它没有编译,因为比较被隐式删除了。

struct Tree {
    std::vector<Tree> child;

    friend auto operator<=>(const Tree &a, const Tree &b) = default;
}
int main(){
    Tree t;
    std::cout<<(t<t)<<std::endl;
}

谁能向我解释如何解决这个问题,或者至少为什么它不起作用?

编辑:使用“g++ -std=gnu++2a main.cpp”编译 编辑2: 这是输出的错误部分(后面是很多很多行候选):

main.cpp: In function 'int main()':
main.cpp:31:25: error: use of deleted function 'constexpr auto operator<=>(const Tree&, const Tree&)'
   31 |     std::cout << (tmp < tmp) << std::endl;
      |                         ^~~
main.cpp:12:17: note: 'constexpr auto operator<=>(const Tree&, const Tree&)' is implicitly deleted because the default definition would be ill-formed:
   12 |     friend auto operator<=>(const Tree &a, const Tree &b) = default;
      |                 ^~~~~~~~
main.cpp:12:17: error: no match for 'operator<=>' (operand types are 'std::vector<Tree>' and 'std::vector<Tree>')

【问题讨论】:

  • 我猜这与Treevector中使用时不完整有关。
  • 好吧 gerum sais 比较 t
  • @Goodies, = default 用于生成算子的默认定义。无论您传入什么值,该定义都存在——它基于类型。
  • 我认为 main() 中的测试太短了。有一个实例 t,但它有一个 empty vector 子级。我把这个留给 cpp 专家,但我觉得这段代码被优化掉是合乎逻辑的。没有真正的“比较”,因此编译器将替换为 false ?.
  • @Goodies 是的,它可能会被优化掉,但根据 as if 规则,这不会改变任何东西。

标签: c++ c++20 spaceship-operator


【解决方案1】:

您通常不能定义具有推导返回类型的递归函数。为了推断它,你需要已经知道它,所以这是不行的。

auto 替换为显式返回类型std::weak_ordering fixes the problem

【讨论】:

  • FWIW,Clang 仍然没有编译它。我不能确定这是否是一个错误。
  • 你是对的,这就是问题所在。我怀疑是和宇宙飞船的世代有关,不过是简单的类型推导。
  • 令人着迷.. 感谢您发布该上帝螺栓链接!
猜你喜欢
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2012-12-14
  • 2011-03-04
  • 2010-10-24
  • 1970-01-01
相关资源
最近更新 更多