【问题标题】:Template function return type deduction in C++03C++03中的模板函数返回类型推导
【发布时间】:2015-05-29 20:17:12
【问题描述】:

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

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

除了我想调用convert 而不必明确指定T1。我怎么做?

【问题讨论】:

  • 如果条件成立,那么你返回值,它必须可以转换为T1,对吧?
  • 不,可以转换的不是必须的。
  • convert模板的第二个参数既没有默认也没有指定?我们希望调用 convert(x) 被上面的模板拾取?
  • ...是吗?我不确定你在暗示什么。
  • @armundle 真的修复了。

标签: c++ templates template-argument-deduction return-type-deduction


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    convert<Obj>(x);
    

    第二个模板参数不必指定,即使第一个模板参数已经明确指定,也可以推导出来(所以总是把需要明确指定的模板参数放在可以推导的参数之前!)。

    但是,这只有在conversionFunction 和T2&amp; 的返回类型都可以转换为T1 时才有效;由于编译器无法知道condition 在运行时有什么值,它必须确保?: 的两个“分支”都是可编译的。在这种情况下,使用typename boost::common_type&lt;T1, ReturnTypeOfConversionFunction&gt;::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*/,type traits from Boost 可能会有所帮助。

    用于Converter 的语法称为部分template specialization。 在指定convert 的返回值时,为什么需要typename,请参阅here。

    【讨论】:

    • 为什么要在Obj上使用模板?
    • 对不起,我误读了您之前版本的答案。只需替换所需的返回类型(T1 的任何你想要的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    相关资源
    最近更新 更多