我有一个索引器函数,并试图将它专门用于标准容器类型,但是会出错。我敢肯定它简单或不可能,但我不记得哪一个。我更喜欢这些作为一个功能对象,但我也无法做到这一点。是否可以为模板类
专门化模板函数namespace std { //declarations of predefined indexable types
template <class T, class A> class vector;
//others are here too, but all have the same issue
}
//default indexer
template <class T>
double indexer(const T& b) { //this seems to work fine
return b.getIndex();
}
// base types
template<> double indexer<char>(const char& b) { return double(b); }
//other primitives are here too, and work fine
// standard library
template<class T, class A>
double indexer<std::vector<T,A>>(const std::vector<T,A>& b)
{ return b.empty() ? 0 : indexer(*b.cbegin()); } //line with error
错误消息:
error C2768: 'indexer' : illegal use of explicit template arguments
我希望这是专门化和重载,因为我有一个函数A
,它接受一个函数对象/指针模板参数,以及重载函数A
,它调用带有默认值的第一个A索引器。
template<class T, class function>
double A(T a, function F) { return F(a);} //complicated
template<class T>
double A(T a) {return A(a, indexer<T>);} //default wrapper
这似乎很可能是一个重复的问题,但我似乎找不到一个。
答案 0 :(得分:2)
您不能部分专门化模板功能,只能模板化类。
改为使用重载:
namespace std { //declarations of predefined indexable types
template <class T, class A> class vector;
}
//default indexer
template <class T>
double indexer(const T& b) { return b.getIndex(); }
double indexer(const char& b) { return double(b); }
template<class T, class A>
double indexer(const std::vector<T,A>& b)
{ return b.empty() ? 0 : indexer(*b.cbegin()); }
答案 1 :(得分:1)
由于函数不能部分专用,我可以用函数对象替换索引器函数。这似乎工作正常,并解决了我所有的问题。
namespace std { //declarations of predefined indexable types
template <class T, class A> class vector;
}
template <class T>
struct indexer {
double operator()(const T& b) const
{ return b.getIndex(); }
};
template<> struct indexer<char> {
double operator()(const char& b) const
{ return double(b); }
};
template<class T, class A> struct indexer<std::vector<T,A>> {
double operator()(const std::vector<T,A>& b) const
{ return b.empty() ? 0 : indexer(*b.cbegin()); }
};
template<class T, class function>
double A(T a, function F) { return F(a);} //complicated
template<class T>
double A(T a) {return A(a, indexer<T>());} //default wrapper
答案 2 :(得分:0)
这是一个完全基于重载的解决方案,使用C ++ 11风格的可变参数模板:
template <typename T>
T print(const T & t)
{
std::cout << t << std::endl;
return t;
}
template <template <typename...> class Container, typename ...Args>
typename Container<Args...>::value_type print(const Container<Args...> & v)
{
typedef typename Container<Args...>::value_type T;
if (v.empty()) std::cout << "nil" << std::endl;
else std::cout << *v.begin() << std::endl;
return v.empty() ? T() : *v.begin();
}
如果您想要花哨,并且您有权访问is_container
类型特征(例如从pretty printer获取),则可以使用{{1}使容器超载特定于容器}:
enable_if