Интересующая функция
Я пытаюсь написать шаблонную функцию sortDifferentWays
, которая будет сортировать (и печатать) вектор, следуя инструкциям функции компаратора.Я не уверен, каковы стандартные способы указания компараторов, но я пошел с
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