基于C ++ 98中的函数对象operator()签名的“重载”函数模板 [英] “Overload” function template based on function object operator() signature in C++98
问题描述
我想创建一个包含函数和向量的模板函数,并使用该函数将该向量映射到函数模板将返回的另一个向量。
如果作为参数的函数是自由函数,它可能有两个签名之一。
// T是函数模板的参数
T sig1(const T x);
T sig2(const T x,const std :: vector< T& v);
它也可以是一个函数对象,其中 operator c $ c>将表现得像自由函数。对于4种可能性中的任何一种使用函数模板应该是透明的。
std :: vector< int& v;
// ... fill v somehow ...
// foo是自由函数或函数对象实例
const std :: vector< int> a = map_vec(foo,v);
我问如何做这个C ++ 11和从0x499602D2得到一个很好的答案。 p>
0x499602D2的答案利用了这两个不同的模板签名在C ++ 11中的事实: / p>
template< typename F,typename T>
auto map_vec(F&& fnc,const std :: vector< T>& source)
- > decltype(void(fnc(std :: declval< T>())),std :: vector< T> {});
模板< 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结构,可以确定一个函数对象是否接受两个args。我不知道如何得到这个工作的功能对象和自由功能。我需要改变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();
模板< typename F,typename T>
typename ignore_value< sizeof(declat>()(declat< T const>())),
std :: vector< T> > :: type map_vec(F fnc,const std :: vector< T& source);
模板< 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模式。
I want to make a template function that takes a function and a vector and uses the function to map that vector to another vector that will be returned by the function template.
If the function taken as an argument is a free function, it may have one of two signatures.
// T is the parameter of the function template
T sig1(const T x);
T sig2(const T x, const std::vector<T>& v);
It may also be a function object in which operator()
would behave like the free functions. Use of the function template for any of the 4 possibilities should be transparent.
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);
I asked how to do this for C++11 and got a great answer from 0x499602D2.
"Overload" function template based on function object operator() signature
0x499602D2's answer makes use of the fact that these are two distinct template signatures in 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>{});
I would also like to know how to solve this in C++98.
Here is my effort so far. I have a SFINAE struct that can determine if a function objects takes two args. I don't know how to get this working for both function objects and free functions. Either I need to change the SFINAE struct to work on both function objects and free functions or I need to use overloading to route function objects and free functions separately.
http://coliru.stacked-crooked.com/a/1471088cbc3b8544
Here's my approach:
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);
It works with the same Demo that 0x499602D2 used, with both GCC and Clang in C++98 mode.
这篇关于基于C ++ 98中的函数对象operator()签名的“重载”函数模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!