有没有办法对在编译时已知的索引进行静态声明,否则对运行时进行声明?例:
template <class T, int Dim>
class Foo
{
T _data[Dim];
public:
const T &operator[](int idx) const
{
static_assert(idx < Dim, "out of range"); // error C2131: expression did not evaluate to a constant
return _data[idx];
}
};
int main()
{
Foo<float, 2> foo;
foo[0];
foo[1];
foo[2]; // compiler error
for (int i=0; i<5; ++i)
{
foo[i]; // run time assert when i > 1
}
return 0;
}
我认为仅凭一个功能就不可能获得想要的东西。
即使您开发了一个constexpr
函数,我也认为您无法检测何时在运行时执行,何时在编译时执行以及以不同的方式执行操作。
但是您可以开发不同的功能。
举例来说,模板get<>()
(其中template参数为索引)只能与编译时已知的索引一起使用static_assert()
,并且可以执行和at(std::size_t)
,可以接收在运行时通过运行时检查计算得出的索引。
顺便说说:
1)我建议像往常一样在STL中,对at()
绑定检查访问和operator[]()
绑定未检查访问使用
2),我建议使用无符号索引,否则您必须检查索引是否为>= 0
。
以下是一个工作示例
#include <iostream>
#include <stdexcept>
template <class T, std::size_t Dim>
class Foo
{
private:
T _data[Dim];
public:
T const & operator[] (std::size_t idx) const
{ return _data[idx]; }
template <std::size_t IDX>
T const & get () const
{
static_assert(IDX < Dim, "out of range");
return this->operator[](IDX);
}
T const & at (std::size_t idx) const
{
if ( idx >= Dim )
throw std::range_error("out of range");
return this->operator[](idx);
}
};
int main ()
{
Foo<float, 2U> foo;
foo.get<0U>();
foo.get<1U>();
//foo.get<2U>(); // compiler error
for ( auto i = 0U ; i < 5U ; ++i )
foo.at(i); // run time exception when i > 1
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句