使用std ::迭代特征和自动定义函数声明的函数
Define a function in function declaration using std::iterator traits and auto
今天我试图实现radix排序。该函数必须具有两个变量:开始迭代器和结束迭代器,并且可以具有第三个:某些函数必须返回整数类型进行排序。默认情况下,它必须是身份函数。
我的尝试看起来像(对不起,代码看起来很长又脏,但这只是一个尝试(:
template<class ForwardIt>
void radix_sort(
ForwardIt first,
ForwardIt last,
std::function<auto(typename std::iterator_traits<ForwardIt>::value_type)> get_value =
[](const typename std::iterator_traits<ForwardIt>::value_type& x){ return x; }) {
// ...
}
当然,返回的get_value类型将在汇编时间。
中知道用法应为:
std::vector<std::pair<uint32_t, std::string>> vec;
// ...
radix_sort(vec.begin(), vec.end(), [](const std::pair<uint32_t, std::string>& x){ return x.first; })
或:
std::vector<uint32_t> vec;
// ...
radix_sort(vec.begin(), vec.end());
它甚至没有编译,我不知道如何解决问题。怎么做?简单示例:
#include <bits/stdc++.h>
template<class ForwardIt>
void radix_sort(
ForwardIt first,
ForwardIt last,
std::function<auto(typename std::iterator_traits<ForwardIt>::value_type)> get_value =
[](const typename std::iterator_traits<ForwardIt>::value_type& x){ return x; }) {
// ...
}
int main()
{
std::vector<std::pair<uint32_t, std::string>> vec(10);
radix_sort(vec.begin(), vec.end());
}
编译器输出:
source_file.cpp:17:37: error: no matching function for call to ‘radix_sort(std::vector<unsigned int>::iterator, std::vector<unsigned int>::iterator)’
radix_sort(vec.begin(), vec.end());
^
source_file.cpp:6:6: note: candidate: template<class ForwardIt, class auto:1> void radix_sort(ForwardIt, ForwardIt, std::function<auto:1(typename std::iterator_traits<_Iter>::value_type)>)
void radix_sort(
^
source_file.cpp:6:6: note: template argument deduction/substitution failed:
source_file.cpp:17:37: note: couldn't deduce template parameter ‘auto:1’
radix_sort(vec.begin(), vec.end());
解决此操作的简单方法是没有默认功能,而是有两个过载。这使您可以摆脱使用std::function
,这是昂贵的,以编写几行锅炉板代码为代价。如果您使用
template<class ForwardIt, class Func>
void radix_sort(ForwardIt first, ForwardIt last, Func get_value) {
// ...
}
template<class ForwardIt>
void radix_sort(ForwardIt first, ForwardIt last) {
radix_sort(first, last, [](const typename std::iterator_traits<ForwardIt>::value_type& x){ return x; });
}
您获得没有函数的默认"身份",如果提供了一个,则可以获得确切的功能对象。
为了未来用户的利益,我想指出的是,C 20引入了std::identity
类,这有助于解决问题。在它的帮助下代码可以被重写为:
template <typename For, typename F = std::identity>
void radix_sort(For first, For end, F f = {})
{
/* ... */
}
,自己实施一个标准符合条件的人非常容易如果您没有C 20,则这样:
struct identity {
template <class T>
constexpr T&& operator()(T&& t) const noexcept
{
return std::forward<T>(t);
}
using is_transparent = void;
};
相关文章:
- 不同翻译单元中不可重载的非内联函数定义
- Visual Studio中的函数声明和函数定义问题
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 具有enable_if外部类原型的模板类构造函数定义
- 类的前向声明之后的类成员函数定义,在类声明之前
- 为函数定义符号不明确的指针参数
- C++模板专用化 - 无法匹配函数定义
- 错误:在第 6 行'{'标记之前,此处不允许使用函数定义
- 找不到 #define 的函数定义
- 根据类型特征更改函数定义?
- 将抽象基类中的所有纯虚函数定义为 varaidaic 模板
- 命名空间更改函数定义
- "Type&"与C++函数定义中的"Type*"
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 如何从 C++ 中的现有模板函数定义新函数
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- 为什么c++允许成员函数定义中实例的私有成员访问
- Qt基类函数定义
- C++函数定义中参数列表后面额外一对括号的含义