【问题标题】:Specialization of template class method模板类方法的特化
【发布时间】:2012-10-13 22:04:49
【问题描述】:

假设我有以下课程:

template <typename T>
class MyClass
{
public:
    void SetValue(const T &value) { m_value = value; }

private:
    T m_value;
};

如何为 T=float(或任何其他类型)编写函数的专用版本?

注意:简单的重载是不够的,因为我只希望函数可用于 T=float(即 MyClass::SetValue(float) 在这种情况下没有任何意义)。

【问题讨论】:

    标签: c++ templates


    【解决方案1】:
    template <typename T>
    class MyClass {
    private:
        T m_value;
    
    private:
        template<typename U>
        void doSetValue (const U & value) {
            std::cout << "template called" << std::endl;
            m_value = value;
        }
    
        void doSetValue (float value) {
            std::cout << "float called" << std::endl;
        }
    
    public:
        void SetValue(const T &value) { doSetValue (value); }
    
    };
    

    或(部分模板特化):

    template <typename T>
    class MyClass
    {
    private:
        T m_value;
    
    public:
        void SetValue(const T &value);
    
    };
    
    template<typename T>
    void MyClass<T>::SetValue (const T & value) {
        std::cout << "template called" << std::endl;
        m_value = value;
    }
    
    template<>
    void MyClass<float>::SetValue (const float & value) {
        std::cout << "float called" << std::endl;
    }
    

    或者,如果您希望函数具有不同的签名

    template<typename T>
    class Helper {
    protected:
        T m_value;
        ~Helper () { }
    
    public:
        void SetValue(const T &value) {
            std::cout << "template called" << std::endl;
            m_value = value;
        }
    };
    
    template<>
    class Helper<float> {
    protected:
        float m_value;
        ~Helper () { }
    
    public:
        void SetValue(float value) {
            std::cout << "float called" << std::endl;
        }
    };
    
    template <typename T>
    class MyClass : public Helper<T> {
    };
    

    【讨论】:

    • 您的部分模板专业化答案一针见血!正是我想要的,谢谢。
    • 实际上,在您的第二个示例中,这是明确的模板专业化:您提供了 1 个模板参数中的所有 1 个,如果有,您需要提供 2 个。另一个关键是,如果您将模板放入头文件并包含两次,这些专用函数显然需要位于单独的编译单元(而不是头文件)中。
    【解决方案2】:

    当然可以。只是它应该是一个过载:)

    template <typename T>
    class MyClass
    {
    public:
        template<class U> 
        void SetValue(const U &value) { m_value = value; }
        void SetValue(float value) {do special stuff} 
    private:
        T m_value;
    };
    
    int main() 
    {
         MyClass<int> mc;
         mc.SetValue(3.4); // the template member with U=double will be called
         mc.SetValue(3.4f); // the special function that takes float will be called
    
         MyClass<float> mcf; //compiles OK. If the SetValue were not a template, 
         // this would result in redefinition (because the two SetValue functions
         // would be the same   
    }
    

    【讨论】:

    • 但我只希望浮点重载在 T=float 时可用。否则,您可能拥有MyClass&lt;int&gt;::SetValue(float),这没有任何意义。
    猜你喜欢
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    相关资源
    最近更新 更多