我尝试实现模板功能专业化。你可以在this小提琴中运行我的小代码。你也可以在下面看到它
#include <iostream>
#include <vector>
#include <list>
template <typename T>
struct is_vector {
static const bool value = false;
};
template <typename T>
struct is_vector<std::vector<T>> {
static const bool value = true;
using type = std::vector<T>;
};
template <typename T>
struct is_list {
static const bool value = false;
};
template <typename T>
struct is_list<std::list<T>> {
static const bool value = true;
using type = std::list<T>;
};
template<typename T, class = typename std::enable_if<is_list<T>::value>::type>
void foo(T t) {
std::cout << "is list" << std::endl;
}
/*
template<typename T, class = typename std::enable_if<is_vector<T>::value>::type>
void foo(T t) {
std::cout << "is vector" << std::endl;
}
*/
//The above code will cause an error, if we uncomment it
int main()
{
foo(std::list<int>{});
return 0;
}
在这段代码中,我有几行注释:
template<typename T, class = typename std::enable_if<is_vector<T>::value>::type>
void foo(T t) {
std::cout << "is vector" << std::endl;
}
如果我取消注释,我会得到&#34; redtifinition&#34;错误。我不确定如何解决它。
答案 0 :(得分:3)
如果我取消注释,我会收到“redifinition”错误。我不确定如何解决它。
原因很简单:模板类型参数的默认值不是函数签名的一部分。这意味着您有两次定义相同的模板。
您可以将 SFINAE 部分移入函数返回类型,如其他答案所示,或将代码更改为:
template<typename T, std::enable_if_t<is_list<T>::value, int> = 0>
void foo(T t) {
std::cout << "is list" << std::endl;
}
template<typename T, std::enable_if_t<is_vector<T>::value, int> = 1>
void foo(T t) {
std::cout << "is vector" << std::endl;
}
答案 1 :(得分:1)
不确定这是否是您所追求的,但您可以检查列表或向量是否匹配类型:
template<typename T, class = typename std::enable_if<is_list<T>::value || is_vector<T>::value>::type>
void foo(T t) {
std::cout << "is list" << std::endl;
}
更新了小提琴:https://godbolt.org/g/oD3o9q
更新(对于C ++ 14):
template<typename T, class = std::enable_if_t<is_list<T>::value || is_vector<T>::value>>
void foo(T t) {
std::cout << "is list" << std::endl;
}
答案 2 :(得分:1)
你可以这样做。
template<typename T>
typename std::enable_if<is_list<T>::value>::type foo(T t) {
std::cout << "is list" << std::endl;
}
template<typename T>
typename std::enable_if<is_vector<T>::value>::type foo(T t) {
std::cout << "is vector" << std::endl;
}