Mar*_*ing 3 c++ standards templates
有一个我正在重构的类,它目前有一个方法:
void resize(size_t sz)
Run Code Online (Sandbox Code Playgroud)
在当前的代码库中,sz始终为0,1,2或3.基础类正在从动态分配更改为maxsize == 3的预分配数组.
如果有人试图调整大小为sz> 3,我怎么能得到构建时错误?添加运行时检查很容易.但我宁愿让编译时检查更快失败.
我不想更改任何使用入站的整数文字进行调用的现有代码,例如:
x.resize(2)
Run Code Online (Sandbox Code Playgroud)
应该仍然按原样编译.
但如果有人出现并试图
x.resize(4)
or
x.resize(n)
Run Code Online (Sandbox Code Playgroud)
它应该无法编译或链接.
我正在考虑一个专门针对int的模板,除了{0,1,2,3}之外的任何其他内容都是未定义的.但我不确定如何在标准c ++的范围内做到我想做的事情.
编辑:
我应该详细说明我使用模板的想法.我非常愿意更改resize函数的声明.我不愿意更改调用代码.
我正在想类似的东西
void resize( ConstructedFromLiteral<0,3> sz)
Run Code Online (Sandbox Code Playgroud)
要么
void resize( ConstructedFromLiteral<0> sz)
void resize( ConstructedFromLiteral<1> sz)
void resize( ConstructedFromLiteral<2> sz)
void resize( ConstructedFromLiteral<3> sz)
Run Code Online (Sandbox Code Playgroud)
您无法获得运行时值的编译时检查.想象一下,如果你说,
resize(read_some_number_from_disk());
Run Code Online (Sandbox Code Playgroud)
编译器应该如何检查?
但是,您可以将该函数设置为模板,因为模板参数在编译时是已知的:
class Foo
{
template <unsigned int N> void resize()
{
static_assert(N < 4, "Error!");
//...
}
//...
};
Run Code Online (Sandbox Code Playgroud)
如果你没有静态断言,你可以装配你自己的静态断言类,它将无法编译:
template <bool> struct ecstatic_assert; // no definition!
template <> struct ecstatic_assert<true> { } ;
Run Code Online (Sandbox Code Playgroud)
用法:
... resize ... { ecstatic_assert<N < 4> ignore_me; /* ... */ }
Run Code Online (Sandbox Code Playgroud)