【问题标题】:Is it possible to change return type of a specialized template function?是否可以更改专用模板函数的返回类型?
【发布时间】:2015-08-23 07:05:31
【问题描述】:

这是我想做的:

template<int I> struct banana {
    float number;
    banana(float n) {
        number = n;
    }

    int getNumber() { 
        return number; 
    }
};

template<> float banana<0>::getNumber() {
    return number;
}

所以当一个新的香蕉 生成时,它会以浮点数而不是整数的形式返回数字。编译器不会让我。

我找到了看似相同问题https://stackoverflow.com/a/15912228/4049658 的答案(尽管如此,我可以使用 c++ 11 但不是 14,如果这会有所不同)但我不明白它是如何工作的,或者它是否甚至是相同的东西。

【问题讨论】:

  • 您的代码示例看起来很荒谬。你真正想达到什么目标?
  • 这在我看来不像模板函数,更像是(模板化)类中的普通函数。
  • 这是我想在课堂上添加的品质的最小说明。真正的类是模板类型数据数组的包装器,它应该总是返回浮点数。由于某些受支持的原始数据类型是不可分割的,因此我需要重新解释它们,因此我返回一个代理,该代理具有为括号运算符中的赋值运算符定义的 setter 函数。
  • 所以答案是“是的,但是示例代码不是模板化函数,而是模板化类”。
  • banana&lt;0&gt; 不作为单独的类存在,它只是模板的实例化(元函数的结果)。您需要将 banana&lt;0&gt; 定义为不同的类(显式模板特化)。

标签: c++ templates template-specialization


【解决方案1】:

一种特殊化返回类型的简单方法是使用 std::conditional:

// First approach: conditional
template<int I> struct banana {
    float number;
    banana(float n) {
        number = n;
    }

    // C++14 std::conditional_t<I == 0, float, int>
    typename std::conditional<I == 0, float, int>::type
    getNumber() {
        return number;
    }
};

或者按照您的建议,您可以使用模板专业化:

template<int /*I*/>
struct banana_return_type
{
    using type = int;
};

template<>
struct banana_return_type<0>
{
    using type = float;
};

template<int I> struct bananaSecond {
    float number;
    bananaSecond(float n) {
        number = n;
    }

    typename banana_return_type<I>::type
        getNumber() {
        return number;
    }
};

Demo

【讨论】:

  • 我认为有必要提一下,对于这两种解决方案,您现在都可以按照 OP 想要的方式编写显式专业化,即类似于 template&lt;&gt; inline float banana&lt;0&gt;::getNumber() { std::cout &lt;&lt; "spec\n"; return number; },以便提供不同的特殊情况 0 的定义。我认为,解释为什么它现在有效,为什么它不适用于问题中的代码以及为什么可能需要inline 将使答案完整。吹毛求疵:OP提到他不能使用C++14,所以std::conditional_t不可用。
【解决方案2】:

给定:

template<int I> struct banana {
    float number;
    banana(float n) {
        number = n;
    }

    int getNumber() { 
        return number; 
    }
};

此时,banana&lt;0&gt; 不是一个独特的用户定义类,而是一个模板的实例化,所以下面的形式不正确:

template<> float banana<0>::getNumber() {
    return number;
}

您需要使banana&lt;0&gt; 是一个明确定义的类:一个显式模板特化

template<> struct banana<0> {
    float number;
    banana(float n) {
        number = n;
    }

    float getNumber() { 
        return number; 
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    相关资源
    最近更新 更多