仅专门化模板类的一个方法(的一部分)

ffe*_*rri 6 c++ templates specialization template-specialization

如果我有一个模板类

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

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

编辑:我正在 C++11 中开发

Jar*_*d42 6

您可以像这样使用专门化(不需要专门化整个类):

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


Vit*_*meo 5

如果您只需要更改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;
}
Run Code Online (Sandbox Code Playgroud)

在 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在 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);
}
Run Code Online (Sandbox Code Playgroud)