关于索引的static_assert在编译时知道

沙威

有没有办法对在编译时已知的索引进行静态声明,否则对运行时进行声明?例:

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;
}
最高66

我认为仅凭一个功能就不可能获得想要的东西。

即使您开发了一个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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在编译时确认自动推断类型的假设?(即static_assert样式

C ++ static_assert和编译时

在使用static_assert时如何避免关于没有返回表达式的警告?

验证(使用static_assert)元组类型是否遵循某种顺序(有状态编译时检查)

数组大小应在编译时知道

如何检测编译器是否支持static_assert?

static_assert和Intel C ++编译器

Rust错误:在编译时无法知道类型(dyn std :: error :: Error +'static)的值的大小

数组可以在编译时索引吗?

如何使“ static_assert”打印失败时得到的值?

如何在使用函数时使static_assert失败

关于在编译和链接C ++文件时的-ldl标志

关于在编译时链接Boost库的困惑

constexpr if和static_assert

使用SFINAE的static_assert

我不知道为什么这个static_assert()代码不起作用

是否可以为不应编译的表达式表达static_assert?

将CRTP与static_assert一起使用时的编译器错误

static_assert(std :: is_abstract)在Visual Studio 2013中导致编译器错误

与static_assert和boost :: hana相关的Clang编译错误

如果constexpr在lambda中带有static_assert,哪个编译器正确?

static_assert 导致程序无法编译,即使断言位于函数模板的头文件中

尽管编译时间常数为 static_assert,但专用模板 *not* 断言

为什么在编译时不执行[static N]?

static_assert和类模板

static_assert取决于类模板

static_assert 的最佳位置是什么?

static_assert宽字符文字的签名?

有条件的static_assert