基于 C++98 中函数对象运算符 () 签名的“重载”函数模板
“Overload” function template based on function object operator() signature in C++98
我想创建一个模板函数,该函数接受一个函数和一个向量,并使用该函数将该向量映射到函数模板将返回的另一个向量。
如果作为参数的函数是自由函数,则它可能具有两个签名之一。
// T is the parameter of the function template
T sig1(const T x);
T sig2(const T x, const std::vector<T>& v);
它也可以是函数对象,其中operator()
的行为类似于自由函数。对 4 种可能性中的任何一种使用函数模板应该是透明的。
std::vector<int> v;
// ... fill v somehow ...
// foo is either free function or function object instance
const std::vector<int> a = map_vec(foo, v);
我问如何为C++11做到这一点,并从0x499602D2那里得到了很好的答案。
基于函数对象运算符 (( 签名的"重载"函数模板
0x499602D2的回答利用了 C++11 中这是两个不同的模板签名这一事实:
template<typename F, typename T>
auto map_vec(F&& fnc, const std::vector<T>& source)
-> decltype(void(fnc(std::declval<T>())), std::vector<T>{});
template<typename F, typename T>
auto map_vec(F&& fnc, const std::vector<T>& source)
-> decltype(void(fnc(std::declval<T>(), source)), std::vector<T>{});
我还想知道如何在 C++98 中解决这个问题。
这是我迄今为止的努力。我有一个 SFINAE 结构,可以确定函数对象是否需要两个参数。我不知道如何让它同时适用于函数对象和自由函数。要么我需要更改 SFINAE 结构以同时处理函数对象和自由函数,要么需要使用重载来分别路由函数对象和自由函数。
http://coliru.stacked-crooked.com/a/1471088cbc3b8544
这是我的方法:
template <std::size_t, typename T = void> struct ignore_value {typedef T type;};
template <typename T>
T& declval();
template<typename F, typename T>
typename ignore_value<sizeof(declval<F>()(declval<T const>())),
std::vector<T> >::type map_vec(F fnc, const std::vector<T>& source);
template<typename F, typename T>
typename ignore_value<sizeof(declval<F>()
(declval<T const>(), declval<const std::vector<T> >())),
std::vector<T> >::type map_vec(F fnc, const std::vector<T>& source);
它与0x499602D2使用的演示相同,GCC 和 Clang 都处于 C++98 模式。
相关文章:
- 将重载的成员函数传递给函数模板
- 使用模板重载函数
- 函数模板实例化、替换和重载解析的顺序是什么?
- 基于 SFINAE 的特征实现问题与函数模板重载
- 如何通过签名作为模板参数来解决重载函数?
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- 重载模板<类型名...>类的函数模板
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 按返回类型重载函数模板
- 定义重载C++函数模板的原型时,使用其名称引用以前的定义是否合法?
- 用另一个函数模板重载函数模板合法吗
- 获取重载函数模板的地址
- 部分专用结构与重载函数模板
- 基于参数函数参数类型重载函数模板
- 重载函数模板
- 基于 C++98 中函数对象运算符 () 签名的“重载”函数模板
- 具有引用参数的重载函数模板
- 用子类调用时匹配模板而不是基类的重载函数模板
- 有时可以使用重载函数模板的地址
- 在命名空间中重载函数模板