假设我具有以下功能:
void mergesort(auto first, auto last) {
if(last - first > 1) {
auto middle = first + (last - first) / 2;
merge_sort(first, middle);
merge_sort(middle, last);
std::inplace_merge(first, middle, last);
}
}
我想将
mergesort
用作另一个函数的参数(也返回void
)。阅读其他一些SO问题之后,我尝试了以下方法:
void sort(auto args, std::function<void (auto, auto)> sorter) {
// some stuff
sorter(args.l.begin(), args.l.end());
// some other stuff
}
// called by:
sort(args, mergesort);
并且。
void sort(auto args, void (*sorter)(auto, auto)) {
sorter(args.l.begin(), args.l.end());
}
// called by:
sort(args, mergesort);
上面的尝试我也尝试改变指针等,以防万一我忘记了什么。
这些都不起作用,它们返回错误:
no matching function call to 'sort(p_args<long double>&, <unresolved overloaded function type>)'
args
参数是模板化的结构,它工作正常,我在传递函数mergesort
时遇到麻烦。如何解决此错误?
最佳答案
任何C++标准都不允许将auto
用作函数参数类型。 (在某些版本的Concepts提案中可能是这样,但不久前C++ 2a接受的Concepts版本也不允许这样做。)
我相信g++支持使用auto
作为函数参数类型作为编译器扩展。这实际上所做的就是将一个函数转换为一个函数模板,其中每个auto
都用模板类型参数替换。但这仅适用于实际的函数声明和函数定义。即使使用此编译器扩展,也无法创建指向void (*)(auto, auto)
或std::function<void(auto, auto)>
函数的指针,因为在两种情况下,您都需要特定的函数类型,而不需要某种模板。
因此,您可能应该将代码更改为仅显式使用可移植的模板:
template <typename Iter>
void mergesort(Iter first, Iter last) { /*...*/ }
template <typename Args, typename Func>
void sort(Args& args, Func&& sorter) {
std::forward<Func>(sorter)(args.l.begin(), args.l.end());
}
(请注意,我假设您可以对
mergesort
的两个参数强制使用相同的推导类型,尽管我相信g++会将原始void (auto, auto)
声明视为两个独立的类型。)
关于c++ - 带有 “auto”或模板类型推导的功能: “no matching function for call to…” ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46146719/