简体   繁体   中英

Sorting function returns wrong object type on C++17

For some reason when I try to compile the following code with the -std=c++17 flag I get the following error.

The code:

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

The error:

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); });
      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For some reason when I create a std::function<bool(int)> and store the lambda inside it, then pass the function pointer I don't get this error

Code that works:

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

Does anyone know the reason for this behavior? When I compile without the std flag, or when I compile on Windows I don't get that error. GCC version 10.2., on Arch Linux.

The partition function returns an iterator!

Try this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM