如何使用通用的TR1函数对象包装多个函数重载?

5

我有一个函数foo(),它是在库的上下文中提供的。该库为此函数定义了一些重载形式,如:

char foo(float x, int y);
short foo(double x, char y);

我编写了上面的参数/结果类型。重点是,参数类型与重载函数对应的返回类型之间没有通用关系。
这个想法是,库用户可以根据需要为他们自己定义的用户类型添加foo()的重载。函数重载非常容易实现这一点。
我希望使foo()函数族可在Boost.Proto表达式中使用。为此,我认为我需要使用模板调用运算符将上述内容包装在函数对象中:
struct foo_wrap
{
    template <typename A1, typename A2>
    result_type operator()(A1 a1, A2 a2) { return foo(a1, a2); }
};

问题在于如何定义result_type。我意识到使用C++11以及decltype()和尾随函数返回类型会很容易,但是我正在寻找一个C++03的解决方案。因此,foo_wrap需要是一个TR1风格的函数对象。我需要找到一种方法,将result_type定义为参数类型A1A2的编译时函数。这不仅适用于operator()的返回类型,也适用于TR1的result_of协议。简而言之:
  • 是否存在元编程技术,可以根据函数名和一组参数类型,得出该函数对应的返回类型?
  • 或者,是否有其他技术可以用来包装一个具有多个重载的函数,并使其成为通用函数对象?

在支持多种编译器方面,你需要考虑有多具备可移植性? - cdhowie
我希望支持任何相对兼容C++03的编译器,可能至少需要gcc 4.1以上版本。我不是特别关心MSVC,尽管如果它也能在那里运行就更好了。 - Jason R
如果g++是您的主要目标,则可能可以在此处使用其专有的typeof()功能。 - cdhowie
谢谢,这似乎值得一看。它看起来几乎相当于 decltype,所以可能可以完成工作。看起来它也适用于 clang,这很好。拥有更标准的技术会更好,但我怀疑可能没有。 - Jason R
有没有元编程技术,可以根据函数名和一组参数类型,得出函数对应的返回类型?在C++中,你不能传递重载集(无论是作为函数参数还是模板参数)。对于具有多个operator()重载的类类型,boost::result_of也存在类似的问题,并且它们在C++03中没有自动解决方案。当然,手动解决方案是定义一个(手动)映射,将参数类型与返回类型对应起来。 - dyp
@dyp:感谢您的建议。也许我可以定义一个宏来帮助用户创建额外的重载函数。给定一组参数类型和结果类型,该宏可以发出foo_wrap::result<>的特化(根据TR1协议需要),除了函数签名之外。类似这样:DECL_FUNC_OVERLOAD(foo, char, float, int) { /* implementation here */ } - Jason R
1个回答

4
您可以手动为其提供一个特征:
template <typename A1, typename A2>
struct foo_wrap_result;

使用

struct foo_wrap
{
    template <typename A1, typename A2>
    typename foo_wrap_result<A1, A2>::type
    operator()(A1 a1, A2 a2) const { return foo(a1, a2); }
};

并且特化特征:

template <>
struct foo_wrap_result<float, int> { typedef char type; };

template <>
struct foo_wrap_result<double, char> { typedef short type; };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接