基于C ++ 98中的函数对象operator()签名的“重载”函数模板

时间:2014-12-05 20:25:19

标签: c++ templates sfinae overloading 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得到了很好的答案。

"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结构以处理函数对象和自由函数,或者我需要使用重载来分别路由函数对象和自由函数。

http://coliru.stacked-crooked.com/a/1471088cbc3b8544

1 个答案:

答案 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模式。