问题
If I have a template class
template<typename T>
class C {
public:
void method1() { ... }
void method2() { ... }
std::string method3(T &t) {
// ...
std::string s = t.SerializeToString();
// ...
return s;
}
// ...
};
and I want to specialize it for T = std::string
but only changing method3(T&)
(keeping all other methods), or even better, only that part of method3, which for T = std::string
would simply become std::string s = t;
, with minimum impact on current code (less repetition of methods signatures, less subclassing), how would I do it?
EDIT: I'm developing in C++11
回答1:
You can use specialization like that (no need to specialize the whole class):
template<>
std::string C<string>::method3(string &t) {
// ...
std::string s = t;
// ...
return s;
}
回答2:
If you only need to change s
's initialization, you can use overloading:
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;
}
In C++17, you can use 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;
}
}
In C++14, you can use 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);
}
来源:https://stackoverflow.com/questions/47035541/specialize-only-a-part-of-one-method-of-a-template-class