我最近正在研究一个C++库,在那里我设计了一个模板类,出于效率和安全的原因,我们需要特别是非多态的。为了确保以后我没有忘记这一点,并意外地破坏了一切,我认为我会成为一个好公民,并为此添加静态断言。确保模板类不是多态的?
我最初尝试是这样的:
template <typename T> class VirtualVerboten {
...
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
};
这并不是因为编译,在我使用VirtualVerboten
的时间,这是一个不完整的类型。如果这是一个非模板类,我只是把static_assert
类型之后:
class NonTemplateVirtualVerboten {
...
}
static_assert(!std::is_polymorphic<NonTemplateVirtualVerboten>::value,
"This should not be polymorphic.");
但由于这是一个模板类,使得“模板static_assert
”的类似想法是不合法的:
template <typename T> class VirtualVerboten {
...
};
template <typename T>
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
我想出了解决的办法是找到VirtualVerboten
内的成员函数,将有可能被用来当模板实例化(具体而言,构造函数),然后把静态断言在那里:
template <typename T> class VirtualVerboten {
VirtualVerboten();
};
template <typename T>
VirtualVerboten<T>::VirtualVerboten() {
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Yay!
doSomeActualThingsAtRuntime();
}
这是有效的,只是它依赖于这个特定的构造函数实际上会被调用并因此实例化的事实,如果有多个可以调用的构造函数会失败。
有没有一种“万无一失”的方式来在这里添加这个静态断言?我明白为什么原始代码会产生一个错误,为什么你不能有模板静态断言,所以这更像是“我错过了另一种这样做的方式吗?”而不是“这就是为什么你所做的不起作用。”
呃?构造函数?不得不在某个地方建造这个类。在那里推你的静态断言。 –
@SamVarshavchik这就是我最终做的。也许我应该编辑这个问题,使其更清晰。 – templatetypedef
您只需要将某个类型封装在某个相关的东西中,这样只会在第二阶段中检查静态断言。 –