Function of interest
I am trying to write a templated sortDifferentWays
function that will sort (and print) a vector following instructions of a comparator function. I am not sure what is the standard ways to indicate comparators but I went with
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);
}
}
Example of implementation
The function can for example be implemented in the code
#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;
}
, which outputs
{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}
as expected. I welcome advice as to how improve this function but my main question is the following.
Question
I would now like sortDifferentWays
to have a default comparators
argument containing a single function which will work well with most (maybe all) primitive types.
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;
}
But it fails to compile with error message
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;}})
I tried defining a defaultComparator
as
template<typename T>
bool defaultComparator(const T& left, const T& right)
{
return left < right;
}
and give comparators = {&defaultComparator}
but it did not work either and produced the error message
error: reference to overloaded function could not be resolved; did you mean to call it?
How can I make a default comparator?
EDIT
I am compiling with
g++ test.cpp -o a -std=c++11
where g++
is defaulted to 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