我想致电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
是任何其他类型”。我该如何处理?
答案 0 :(得分:4)
对于模板:
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);
}
答案 1 :(得分:3)
T
的 template<typename T> void foo_impl(const std::string &data, std::string *)
是不可导入的(也就是说,它不在函数的参数列表中使用),因此,它不被视为可行的重载。
您可以删除template<typename T>
部分并将此重载设为非模板:
void foo_impl(const std::string &data, std::string *) {
std::cout << "foo for std::string called\n";
}
答案 2 :(得分:2)
我不清楚你为什么要使用两层功能..
您可以为foo
和std::string
重载std::vector<T>
。
#include <iostream>
#include <vector>
#include <string>
template<typename T> void foo(const T &data) {
std::cout << "foo for general types called\n";
}
template <typename T> void foo(const std::vector<T> &data) {
std::cout << "foo for std::vector<T> called\n";
}
void foo(const std::string &data) {
std::cout << "foo for std::string called\n";
}
int main() {
int i = 1;
foo(i);
std::vector<int> a = {0, 1};
foo(a);
std::string s = "abcd";
foo(s);
return 0;
}
输出:
foo for general types called
foo for std::vector<T> called
foo for std::string called