我想调用template<typename T> foo(T x)
并手动处理这些情况:T = std::vector<U>
, T = std::string
, T =
任何其他情况。
这是我为此写的:
#include <iostream>
#include <vector>
#include <string>
template<typename T> void foo_impl(const std::string &data, std::string *) {
std::cout << "foo for std::string called\n";
}
template<typename T> void foo_impl(const T &data, T *) {
std::cout << "foo for general types called\n";
}
template<typename T> void foo_impl(const std::vector<T> &data, std::vector<T> *) {
std::cout << "foo for std::vector<T> called\n";
}
template<typename T> void foo(const T &data) {
foo_impl(data, static_cast<T*>(nullptr));
}
int main() {
int i = 1;
foo(i);
std::vector<int> a = {0, 1};
foo(a);
std::string s = "abcd";
foo<std::string>(s);
return 0;
}
然而,foo(std::string x)
在“T
是任何其他类型”的情况下被调用。我该如何处理?
最佳答案
对于模板:
template<typename T> void foo(const T &data) {
std::cout << "foo for general types called\n";
}
以下是特化:
template<> void foo<>(const std::string &data) {
std::cout << "foo for std::string called\n";
}
但简单的重载似乎更合适:
void foo(const std::string &data) {
std::cout << "foo for std::string called\n";
}
由于函数无法进行部分特化,因此您必须对 vector
情况进行重载:
template<typename T, typename Alloc> void foo(const std::vector<T, Alloc> &data) {
std::cout << "foo for std::vector<T, Alloc> called\n";
}
另一种方法是转发到可以(部分)专门化的类/结构:
template <typename T>
struct foo_impl {
void operator (const T&) const
{
std::cout << "foo for general types called\n";
}
};
// specialization for std::string
template <>
struct foo_impl<std::string>
{
void operator (const T&) const
{
std::cout << "foo for std::string called\n";
}
};
// partial specialization for std::vector
template <typename T, typename A>
struct foo_impl<std::vector<T, A>>
{
void operator (const std::vector<T, A>&) const
{
std::cout << "foo for std::vector<T, A> called\n";
}
};
template <typename T>
void foo(const T& t)
{
foo_impl<T>{}(t);
}
关于c++ - 模板特化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33241678/