【发布时间】:2016-12-30 02:47:51
【问题描述】:
我最近在一个 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 这就是我最终要做的。也许我应该编辑问题以使其更清楚。
-
您只需要将类型封装在依赖项中,因此仅在第二阶段检查静态断言。
-
@KerrekSB 你能在这里发布类似的答案吗?
-
似乎 dtor 可能是一个更好的选择。只有其中一个需要担心(即没有重载)。
标签: c++ c++11 templates typetraits static-assert