感兴趣的函数
我正在尝试编写一个模板化的 sortDifferentWays
函数,它将按照比较器函数的指令对 vector 进行排序(并打印)。我不确定指示比较器的标准方法是什么,但我选择了
template<typename T>
void sortDifferentWays(std::vector<T>& v, std::vector<bool (*)(T,T)> comparators)
{
for (auto& comparator : comparators)
{
std::sort(v.begin(), v.end(), comparator);
printVec(v);
}
}
实现示例
例如可以在代码中实现该功能
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
class X
{
public:
int a;
int b;
X (int A, int B)
: a(A), b(B)
{}
std::string toString()
{
return "{"+std::to_string(a)+","+std::to_string(b)+"}";
}
};
void printVec(std::vector<int> v)
{
for (auto& elem : v)
std::cout << elem <<" ";
std::cout << "\n";
}
void printVec(std::vector<X> v)
{
for (auto& elem : v)
std::cout << elem.toString() <<" ";
std::cout << "\n";
}
bool compare_a(X left, X right)
{
return left.a < right.a;
}
bool compare_b(X left, X right)
{
return left.b < right.b;
}
template<typename T>
void sortDifferentWays(std::vector<T>& v, std::vector<bool (*)(T,T)> comparators)
{
for (auto& comparator : comparators)
{
std::sort(v.begin(), v.end(), comparator);
printVec(v);
}
}
int main()
{
std::vector<X> v = {{1,5},{4,4},{9,2},{4,4},{0,6},{12,2},{11,9}};
sortDifferentWays(v, {&compare_a, &compare_b});
return 0;
}
,输出
{0,6} {1,5} {4,4} {4,4} {9,2} {11,9} {12,2}
{9,2} {12,2} {4,4} {4,4} {1,5} {0,6} {11,9}
如预期。我欢迎就如何改进此功能提出建议,但我的主要问题如下。
问题
我现在希望 sortDifferentWays
有一个默认的 comparators
参数,其中包含一个函数,该函数适用于大多数(可能是所有)原始类型。
template<typename T>
void sortDifferentWays(std::vector<T>& v, std::vector<bool (*)(T,T)> comparators = {[](const T& left, const T& right) -> bool{return left < right;}})
{
for (auto& comparator : comparators)
{
std::sort(v.begin(), v.end(), comparator);
printVec(v);
}
}
int main()
{
std::vector<X> v = {{1,5},{4,4},{9,2},{4,4},{0,6},{12,2},{11,9}};
sortDifferentWays(v, {&compare_a, &compare_b});
std::vector<int> v2 = {4,5,8,3,9,10,2};
sortDifferentWays(v2);
return 0;
}
编译失败,报错
test.cpp:47:70: error: no matching constructor for initialization of 'std::vector<bool (*)(int, int)>'
void sortDifferentWays(std::vector<T>& v, std::vector<bool (*)(T,T)> comparators = {[](const T& left, const T& right) -> bool{return left < right;}})
我尝试将 defaultComparator
定义为
template<typename T>
bool defaultComparator(const T& left, const T& right)
{
return left < right;
}
并给出 comparators = {&defaultComparator}
但它也不起作用并产生了错误消息
error: reference to overloaded function could not be resolved; did you mean to call it?
如何制作默认比较器?
编辑
我正在编译
g++ test.cpp -o a -std=c++11
其中 g++
默认为 clang (MAC OSX)
g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
最佳答案
我在这个例子中看到了几个问题,但是,您正在搜索的问题与参数 comparators
有关。 .
这已被定义为 std::vector<bool (*)(T,T)>
,这是一个函数指针 vector 。但是,您尝试使用 {[](const T& left, const T& right) -> bool{return left < right;}}
对其进行初始化.这是 lambda 的 initializer_list,不可转换。
这背后的原因是,lambda 是用 operator()
编写类的一种快速方法。重载。
class lambda
{
public:
template<typename T1, typename T2>
auto operator()(const T1 &left, const T2 &right) const -> bool { return left < right; }
};
显然,此类不能转换为函数指针。
为了同时处理函数指针和类(又名仿函数),您最好使用类型 std::function
来自 <functional>
.在你的情况下 std::function<bool(T,T)>
.
编辑 Monkey0506 表示如果没有捕获并且它们具有相同的签名,lambda 可以转换为函数指针。最后一个不是这种情况,因为 lambda 的参数是 const 引用。
关于c++ - 比较器函数 vector 的默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50669349/