我有一个表示数值数组的模板类。
我希望这个类适用于任何类型的数值(例如int,double等)和三种类型的容器(std :: vector,std :: deque和std :: list)。
以下是我的具体问题的实施的相关部分:
template < typename Numeric_t, typename Container = std::vector<Numeric_t> >
class Array {
// field member
Container m_data;
// other stuff here
// ...
// random element access for std::vector and std::deque
Numeric_t & operator[] (unsigned int index) { return m_data[index]; }
// random element access for std::list
Numeric_t & operator [] (unsigned int index) {
std::list<Numeric_t> :: iterator it = m_data.begin();
std::advance(it, index);
return *it;
}
}
当然,编译器不允许我重载运算符[] 。
我需要的是对std :: list特定的 operator [] 的部分特化,但在C ++中不允许部分模板函数特化。
(我知道随机元素访问对列表效率不高,但这不是重点。)
理想情况下,在客户端代码中我想使用这样的Array类:
Array < int, std::vector<int> > vec;
Array < int, std::list<int> > lst;
// fill arrays here
// ...
std::cout << vec[0] << std::endl;
std::cout << lst[0] << std::endl;
经过大量研究后,我无法找到可行的解决方案。
解决这个问题最优雅的方法是什么?
感谢您的帮助。
答案 0 :(得分:1)
一个干净的解决方案是使用全班模板专业化。可以从一个公共基类派生不同的特化,以便共享公共代码。
编写一个类ArrayBase
,其中包含所有不依赖于特定容器类型的代码,并通过使其受保护或使Array
为朋友类来授予对容器的访问权。
template <class Numeric_t, class Container>
class Array
: public ArrayBase<Numeric_t, Container>
{
// Container specific code, generic version that works for all containers.
};
template <class Numeric_t>
class Array<Numeric_t, std::vector<Numeric_t>>
: public ArrayBase<Numeric_t, std::vector<Numeric_t>>
{
// Optimized code for std::vector.
}
另一种方法:您还可以编写一个包含代码的静态成员函数来访问容器的 idx
条目并专门化该函数:
template <class Numeric_t, class Container>
class Array
{
template <class Cont>
static Numeric_t get(Cont const& container, unsigned int idx)
{
std::list<Numeric_t>::iterator it = container.begin();
std::advance(it, idx);
return *it;
}
template <>
static Numeric_t get(std::vector<Numeric_t> const& container, unsigned int idx)
{
return container[idx];
}
public:
Numeric_t operator[](unsigned int idx) const { return get(m_data, idx); }
};
击> <击> 撞击>
对不起,这不起作用。我忘了你不能再专门化静态成员函数了。
另一种选择是使用SFINAE,但它是非惯用的,在这种情况下我不会推荐它。