sky*_*gle 13 c++ templates traits
我已经有一段时间没有使用C++的高级功能了,并且正在刷新我的C++知识.话虽如此,基于特征和策略编程的概念是我从未真正设法解决的问题.
我想改变这一点.我正在写一个通用容器.我想强制执行一个策略,即容器只存储从特定基类派生的类.这是因为当尝试访问向量边界外的项时,容器返回无效对象(而不是抛出).
template <class T>
class GenericContainer
{
private:
typedef std::vector<T> TypeVect;
void addElement(const T& elem);
TypeVect m_elems;
public:
unsigned int size() const;
T& elementAt(const unsigned int pos);
const T elementAt(const unsigned int pos) const;
};
Run Code Online (Sandbox Code Playgroud)
我如何使用traits来限制这个泛型容器只包含类'ContainerItem'的子类?
Fre*_*abe 12
您可以使用一个IsDerivedFrom只能在给定类型"D"继承另一个类型"B"的情况下实例化的小模板(此实现取自一个很好的Guru Of The Week文章):
template<typename D, typename B>
class IsDerivedFrom
{
static void Constraints(D* p)
{
B* pb = p; // this line only works if 'D' inherits 'B'
pb = p; // suppress warnings about unused variables
}
protected:
IsDerivedFrom() { void(*p)(D*) = Constraints; }
};
// Force it to fail in the case where B is void
template<typename D>
class IsDerivedFrom<D, void>
{
IsDerivedFrom() { char* p = (int*)0; /* error */ }
};
Run Code Online (Sandbox Code Playgroud)
您现在可以IsDerivedFrom使用继承简单地实例化模板:
template <class T>
class GenericContainer : public IsDerivedFrom<T, ContainerItem>
{
...
};
Run Code Online (Sandbox Code Playgroud)
此代码仅在T继承时编译ContainerItem.
您可以使用boost :: mpl强制执行此操作,以便在编译时断言类型从基类继承.
"滚动你自己"非常简单:
template <typename D, typename B>
class is_derived_from {
class No { };
class Yes { No no[2]; };
static Yes Test(B*);
static No Test(...);
public:
enum { inherits = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
static bool is_derived() { return inherits; }
};
Run Code Online (Sandbox Code Playgroud)
我认为这最初来自GoTW.您所需要的只是一个合适的断言机制(编译时间可能更好).通常的技巧是创建一个宏,使得一个负大小的数组使assert失败,或者1传递它.