仅专门化模板的一种方法(的一部分)class

specialize only (a part of) one method of a template class

如果我有模板class

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&) (保留所有其他方法),或者更好的是,只更改 method3 的那一部分,对于 T = std::string 会简单地变成 std::string s = t;,对当前代码的影响最小(减少方法签名的重复,减少 subclassing),我该怎么做?

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

如果只需要改变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);
}

你可以像那样使用特化(不需要特化整个 class):

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