C++11 理解 (二十八) 之 用于计算函数对象返回类型的统一方法

要在编译期决定一个样板仿函数的回返值类别并不容易,特别是当返回值依赖于函数的参数时。举例来说:

struct Clear {
    int    operator()(int);     // 參數與回返值的型別相同
    double operator()(double);  // 參數與回返值的型別相同
};
 
template <class Obj> 
class Calculus {
public:
    template<class Arg> Arg operator()(Arg& a) const
    {
        return member(a);
    }
private:
    Obj member;
};

实体化样板类 Calculus<Clear>Calculus 的仿函数其回返值总是和 Clear 的仿函数其回返值具有相同的类别。然而,若给定类型 Confused:

struct Confused {
    double operator()(int);     // 參數與回返值的型別不相同
    int    operator()(double);  // 參數與回返值的型別不相同
};

企图实体化样板类 Calculus<Confused> 将导致 Calculus 的仿函数其回返值和类型 Confused 的仿函数其回返值有不同的类别。对于 int 和 double 之间的转换,编译器将给出警告。

模板 std::result_of 被TR1 引进且被 C++11 所采纳,可允许我们决定和使用一个仿函数其回返值的类别。底下,CalculusVer2 对象使用 std::result_of 对象来推导其仿函数的回返值类别:

template< class Obj >
class CalculusVer2 {
public:
    template<class Arg>
    typename std::result_of<Obj(Arg)>::type operator()(Arg& a) const
    { 
        return member(a);
    }
private:
    Obj member;
};

如此一来,在实体化 CalculusVer2<Confused> 其仿函数时,不会有类别转换,警告或是错误发生。

模板 std::result_of 在 TR1 和 C++11 有一点不同。TR1 的版本允许实现在特殊情况下,可以无法决定一个函数调用其回返值类别。然而,因为 C++11支持了decltype,实现被要求在所有情况下,皆能计算出回返值类别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值