gpt4 book ai didi

c++ - 使用 std::sort 时禁止仿函数(继承)?

转载 作者:行者123 更新时间:2023-11-27 22:52:11 25 4
gpt4 key购买 nike

#include <string.h>
#include <vector>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/regex.hpp>

struct FileSorter{

virtual ~FileSorter(){}
virtual bool operator()(const boost::filesystem::path& p1, const boost::filesystem::path& p2) const =0;
};

struct SortByName : public FileSorter{
SortByName(bool ascending=true):ascending_order(ascending)
{
}

virtual bool operator()(const boost::filesystem::path& p1, const boost::filesystem::path& p2) const {
if(ascending_order)
return p1.stem().string() < p2.stem().string();
else
return p1.stem().string() > p2.stem().string();
}

protected:
bool ascending_order;
};

class FilesList : public std::vector<boost::filesystem::path> {
public:
FilesList(const std::string& dir, const std::string& f_regex, const FileSorter& fileSorter=SortByName()) {
boost::regex e(f_regex, boost::regex::perl);
boost::filesystem::path path(dir);
if(!boost::filesystem::is_directory(path)) {
throw std::runtime_error(path.string()+std::string(" is not a directory\n"));
}

for(boost::filesystem::directory_iterator file(path), f_end; file!= f_end; ++file){
if(boost::regex_match(file->path().filename().string(), e))
this->push_back(file->path());
}

std::sort(this->begin(), this->end(), fileSorter);
}
};

我定义了一个 FileList 类,它执行创建满足正则表达式(f_regex 参数)的文件列表。

要对列表进行排序,可以传递 SortBy*** 结构的实例(继承 from FileSorter)。

问题是 std::sort 函数无法用上面的代码编译,显示以下错误消息。

/usr/include/c++/4.8/bits/stl_algo.h:5483:5: error: cannot allocate an object of abstract type ‘FileSorter’

我不明白这种行为。在我狭隘的知识范围内,带有 operator () 的结构称为 functor,这是将函数作为对象处理的好方法。

众所周知,子类的实例可以通过父类的引用来引用。

但是上面的例子是不同的说法。

我应该更改什么才能使代码正常工作?

如果我对c++有错误的概念,请不要犹豫骂我。

完整的编译错误信息在这里。

$ make
Scanning dependencies of target cpp_factory
[ 11%] Building CXX object CMakeFiles/cpp_factory.dir/libraries/src/FileLister.cpp.o
In file included from /home/ub1404/Application/cpp_factory/libraries/src/FileLister.cpp:5:0:
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h: In constructor ‘FilesList::FilesList(const string&, const string&, const FileSorter&)’:
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:109:57: error: no matching function for call to ‘sort(std::vector<boost::filesystem::path>::iterator, std::vector<boost::filesystem::path>::iterator, const FileSorter&)’
std::sort(this->begin(), this->end(), fileSorter);
^
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:109:57: note: candidates are:
In file included from /usr/include/c++/4.8/algorithm:62:0,
from /home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:11,
from /home/ub1404/Application/cpp_factory/libraries/src/FileLister.cpp:5:
/usr/include/c++/4.8/bits/stl_algo.h:5447:5: note: template<class _RAIter> void std::sort(_RAIter, _RAIter)
sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
^
/usr/include/c++/4.8/bits/stl_algo.h:5447:5: note: template argument deduction/substitution failed:
In file included from /home/ub1404/Application/cpp_factory/libraries/src/FileLister.cpp:5:0:
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:109:57: note: candidate expects 2 arguments, 3 provided
std::sort(this->begin(), this->end(), fileSorter);
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from /home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:11,
from /home/ub1404/Application/cpp_factory/libraries/src/FileLister.cpp:5:
/usr/include/c++/4.8/bits/stl_algo.h:5483:5: note: template<class _RAIter, class _Compare> void std::sort(_RAIter, _RAIter, _Compare)
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
/usr/include/c++/4.8/bits/stl_algo.h:5483:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.8/bits/stl_algo.h: In substitution of ‘template<class _RAIter, class _Compare> void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<boost::filesystem::path*, std::vector<boost::filesystem::path> >; _Compare = FileSorter]’:
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:109:57: required from here
/usr/include/c++/4.8/bits/stl_algo.h:5483:5: error: cannot allocate an object of abstract type ‘FileSorter’
In file included from /home/ub1404/Application/cpp_factory/libraries/src/FileLister.cpp:5:0:
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:49:8: note: because the following virtual functions are pure within ‘FileSorter’:
struct FileSorter{
^
/home/ub1404/Application/cpp_factory/libraries/include/cpp_factory/files/FileLister.h:51:18: note: virtual bool FileSorter::operator()(const boost::filesystem::path&, const boost::filesystem::path&) const
virtual bool operator()(const boost::filesystem::path& p1, const boost::filesystem::path& p2) const =0;
^
make[2]: *** [CMakeFiles/cpp_factory.dir/libraries/src/FileLister.cpp.o] Error 1
make[1]: *** [CMakeFiles/cpp_factory.dir/all] Error 2
make: *** [all] Error 2

最佳答案

如果您查看签名,std::sort 按值获取比较对象:

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

所以当你写的时候:

std::sort(this->begin(), this->end(), fileSorter);

您的对象被切片,您最终尝试实例化一个按值获取抽象类的函数,因此您最终会遇到所有错误。

您需要做的是确保即使 sort 按值进行比较,您也通过引用传递您的值。值得庆幸的是,有一个应用程序!只需使用 std::ref :

std::sort(this->begin(), this->end(), std::ref(fileSorter));

也就是说,您真的需要多态比较器吗?如果您只是将不同的比较函数对象传递给 FilesList 构造函数,您应该更愿意将其设为函数模板:

template <class Sorter>
FilesList(const std::string& dir, const std::string& f_regex, Sorter fileSorter) {
// ...
std::sort(begin(), end(), fileSorter); // now copying is fine
}

这样,您可以直接转发用户传递的内容,避免虚拟调度。

关于c++ - 使用 std::sort 时禁止仿函数(继承)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36309702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com