【问题标题】:Sorting function returns wrong object type on C++17排序函数在 C++17 上返回错误的对象类型
【发布时间】:2021-03-31 16:28:05
【问题描述】:

由于某种原因,当我尝试使用 -std=c++17 标志编译以下代码时,出现以下错误。

代码:

#include <functional>
#include <iostream>
#include <list>

std::list<int> partition(std::list<int>::const_iterator &&begin,
                         std::list<int>::const_iterator &&end,
                         std::function<bool(int)> predicate) {
  std::list<int> result;
  while (begin != end) {
    if (predicate(*begin)) {
      result.push_front(*begin);
    } else {
      result.push_back(*begin);
    }
    begin++;
  }
  return result;
}

int main() {
  std::list<int> numbers{15, 20, 25, -10, -75, 100, -255, 430, 200};

  std::cout << "Original list:" << std::endl;
  for (int &e : numbers) {
    std::cout << e << " ";
  }
  std::cout << std::endl << std::endl;

  std::cout << "[](int num) { return !(num % 2); }" << std::endl;
  std::list<int> result = partition(numbers.cbegin(), numbers.cend(), [](int num) { return !(num % 2); });
  for (int &e : result) {
    std::cout << e << " ";
  }
  std::cout << std::endl;

  return 0;
}

错误:

main.cpp: In function ‘int main()’:
main.cpp:31:36: error: conversion from ‘std::_List_const_iterator<int>’ to non-scalar type ‘std::__cxx11::list<int>’ requested
   31 |   std::list<int> result = partition(numbers.cbegin(), numbers.cend(),
      |                           ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   32 |                                     [](int num) { return !(num % 2); });
      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

由于某种原因,当我创建 std::function 并将 lambda 存储在其中,然后传递函数指针时,我没有收到此错误

有效的代码:

#include <functional>
#include <iostream>
#include <list>

std::list<int> partition(std::list<int>::const_iterator &&begin,
                         std::list<int>::const_iterator &&end,
                         std::function<bool(int)> predicate) {
  std::list<int> result;
  while (begin != end) {
    if (predicate(*begin)) {
      result.push_front(*begin);
    } else {
      result.push_back(*begin);
    }
    begin++;
  }
  return result;
}

int main() {
  std::list<int> numbers{15, 20, 25, -10, -75, 100, -255, 430, 200};

  std::cout << "Original list:" << std::endl;
  for (int &e : numbers) {
    std::cout << e << " ";
  }
  std::cout << std::endl << std::endl;

  std::cout << "[](int num) { return !(num % 2); }" << std::endl;
  std::function<bool(int)> func = [](int num) { return !(num % 2); };
  std::list<int> result = partition(numbers.cbegin(), numbers.cend(), func);
  for (int &e : result) {
    std::cout << e << " ";
  }
  std::cout << std::endl;

  return 0;
}

有人知道这种行为的原因吗?当我在没有 std 标志的情况下编译时,或者当我在 Windows 上编译时,我没有收到该错误。 GCC 版本 10.2.,在 Arch Linux 上。

【问题讨论】:

  • 问题是 ADL 正在启动并错误地找到 std::partition。如果你调用你的函数xpartition,那么它又可以正常工作了。
  • 直到现在才知道像 ADL 这样的东西存在。我怀疑它可能是函数的名称。谢谢你帮我解决这个问题。我已经失去了希望。
  • 线索在这部分错误信息中:" required from '_BIter **std::partition**(_BIter, _BIter, _Predicate) [with _BIter = std::_List_const_iterator ; _Predicate = main()::]'" - 它报告了调用std::partition 的问题。
  • 尝试使用auto进行类型推断,如auto result = partition(...)
  • @4xy 只会让问题变得不那么明显。问题是我命名我的函数partiton 不知道有一个实际的STL 函数std::partition 具有完全相同的签名。我只是使用我们大学提供的名字,但我猜他们甚至没有检查就上传了家庭作业......

标签: c++ list gcc lambda c++17


【解决方案1】:

分区函数返回一个迭代器!

试试这个:

std::list<int>::iterator result = partition(numbers.cbegin(), numbers.cend(), [](int num) { return !(num % 2); });

【讨论】:

  • 对不起!我刚刚看到分区是您的功能...我以为您使用的是 std::partition
  • 我创建的函数应该返回一个列表而不是列表迭代器,问题是我的函数和 STL 函数存在名称冲突。 Raymond 已经在评论部分解决了我的问题,但绝对感谢您帮助我!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多