基于C ++ 98中的函数对象operator()签名的“重载”函数模板 [英] “Overload” function template based on function object operator() signature in C++98

查看:141
本文介绍了基于C ++ 98中的函数对象operator()签名的“重载”函数模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个包含函数和向量的模板函数,并使用该函数将该向量映射到函数模板将返回的另一个向量。



如果作为参数的函数是自由函数,它可能有两个签名之一。

  // 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>

;过载基于函数对象operator()签名的函数模板



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆