我想创建一个带有函数和向量的模板函数,并使用该函数将该向量映射到将由函数模板返回的另一个向量。
如果作为参数的函数是自由函数,它可能有两个签名之一。
// 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得到了很好的答案。
"Overload" function template based on function object operator() signature
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结构,可以确定一个函数对象是否需要两个args。我不知道如何使这个功能对象和自由函数。我需要更改SFINAE结构以处理函数对象和自由函数,或者我需要使用重载来分别路由函数对象和自由函数。
答案 0 :(得分:2)
这是我的方法:
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);
它works with the same Demo that 0x499602D2 used,GCC和Clang都是C ++ 98模式。