c++ 03中模板函数返回类型的推导

Template function return type deduction in C++03

本文关键字:返回类型 函数 c++      更新时间:2023-10-16

我想在c++ 03中实现以下内容:

template <typename T1, typename T2>
T1 convert(bool condition, T2& value)
{
    return condition ? value : conversionFunction(value);
}

除非我想调用convert,而不必显式指定T1。我怎么做呢?

也许你可以使用一个hack。窍门是推迟转换,直到实际使用返回值。返回值是一个helper对象,允许将其自身转换为其他内容。

template <typename T>
struct ConvertHack {
    T &value_;
    const bool cond_;
    ConvertHack (bool cond, T &value) : value_(value), cond_(cond) {}
    template <typename U> operator U () const {
        return cond_ ? value_ : conversionFunction(value_);
    }
};
template <typename T>
ConvertHack<T> convert(bool condition, T& value) {
    return ConvertHack<T>(condition, value);
}

返回类型不会被编译器推断出来(这与返回类型不支持重载是一致的)。你必须显式地指定这个模板参数,例如通过调用

convert<Obj>(x);

第二个模板形参不需要指定,即使第一个模板形参已经被显式指定,它也可以被推导出来(所以总是把需要显式指定的模板形参放在可以推导出来的形参之前!)

但是,只有当conversionFunctionT2&的返回类型都可以转换为T1时才有效;因为编译器不能知道condition在运行时的值是多少,所以它必须确保?:的两个"分支"都是可编译的。在这种情况下,使用typename boost::common_type<T1, ReturnTypeOfConversionFunction>::type作为返回值。如果不能很容易地确定ReturnTypeOfConversionFunction,可以使用Boost.TypeOf.

如果条件可以在编译时求值,并且只依赖于T2,则可以使用模板元编程:

template <bool condition, typename T2>
struct Converter;
template<typename T2>
struct Converter<true, T2> { // If the condition is true, use this.
    typedef T2 type;
    static type doConvert(T2& value) { return value; }
};
template<typename T2>
struct Converter<false, T2> { // If the condition is false, use this.
    typedef ReturnTypeOfConversionFunction type;
    static type doConvert(T2& value) { return conversionFunction(value); }
};
template <typename T2>
typename Converter</* condition */, ReturnTypeOfConversionFunction>::type
convert(T2& value)
{
    return Converter<condition, T2, ReturnTypeOfConversionFunction>::doConvert(value); 
}

代替/* condition*/, Boost中的类型特征可能会有帮助。

用于Converter的语法称为部分模板专门化。在指定convert的返回值时,为什么需要typename,请参阅此处。