1

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

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

除了我想打电话convert而不必明确指定T1. 我怎么做?

4

2 回答 2

2

也许你可以使用黑客。技巧是将转换推迟到您实际使用返回值为止。返回值是一个帮助对象,它允许将自己转换为其他对象。

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);
}
于 2015-05-29T21:01:44.053 回答
0

编译器不推导出返回类型(这与返回类型不支持重载一致)。您必须明确指定此模板参数,例如通过调用

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); 
}

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

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

于 2015-05-29T20:39:25.590 回答