【问题标题】:specialize only (a part of) one method of a template class只专门化模板类的一种方法(部分方法)
【发布时间】:2017-10-31 12:33:23
【问题描述】:

如果我有一个模板类

template<typename T>
class C {
public:
    void method1() { ... }
    void method2() { ... }
    std::string method3(T &t) {
        // ...
        std::string s = t.SerializeToString();
        // ...
        return s;
    }
    // ...
};

我想将它专门用于T = std::string,但只更改method3(T&amp;)(保留所有其他方法),或者更好的是,只更改方法3 的那部分,对于T = std::string,它将简单地变成std::string s = t;,最少对当前代码的影响(减少方法签名的重复,减少子类化),我该怎么做?

编辑:我正在使用 C++11 进行开发

【问题讨论】:

    标签: c++ templates template-specialization specialization


    【解决方案1】:

    您可以使用这样的专业化(无需专门化整个班级):

    template<>
    std::string C<string>::method3(string &t) {
        // ...
        std::string s = t;
        // ...
        return s;
    }
    

    【讨论】:

    • 我发布了一个小例子,但实际上我确实需要专门化整个课程
    • @fferri:你的标题字面意思是“只特化(部分)模板类的一种方法”
    • @Jarod42:您是否建议删除该类的模板参数?或者我误解了你的回答。
    • @fferri 它被称为模板函数。
    • @fferri:如果你专攻整个班级,你也必须重写method1/method2。您可以(完全)只专门化给定的方法。类仍然是模板,方法不是。
    【解决方案2】:

    如果只需要改变s的初始化,可以使用重载:

    std::string init(std::string& t)
    {
        return t;
    }
    
    template <typename T>
    std::string init(T& t)
    {
        return t.SerializeToString();
    }
    
    template <typename T>    
    std::string method3(T &t) {
        // ...
        std::string s = init(t);
        // ...
        return s;
    }
    

    在 C++17 中,你可以使用if constexpr:

    std::string method3(T &t) 
    {
        if constexpr(std::is_same_v<T, std::string>)
        {
            std::string s = t;
            // ...
            return s;
        }
        else
        {
            std::string s = t.SerializeToString();
            // ...
            return s;
        }
    }
    

    在 C++14 中,可以使用static_if:

    std::string method3(T &t) 
    {
        static_if(std::is_same<T, std::string>{})
        .then([](auto& x)
        {
            std::string s = x;
            // ...
            return x;
        })
        .else_([](auto& x)
        {
            std::string s = x.SerializeToString();
            // ...
            return x;
        })(t);
    }
    

    【讨论】:

      最近更新 更多