代码之家  ›  专栏  ›  技术社区  ›  wtom

整型模板参数。错误:在常量表达式中使用“this”

c++
  •  2
  • wtom  · 技术社区  · 8 年前

    我试图在SO中找到一个类似的答案,但没有成功。 问题是,为什么在编译时使用在编译时已知的模板参数值(在编译时已知的类型)被认为是错误?常识告诉我,这个代码可以是正常的。这个案子怎么了? 谢谢!

    #include <array>
    
    using Cont = std::array<int, 2>;
    
    class A
    {
        Cont a_ = {};
    
    public:
        int& at(bool first)
        {
            static_assert(sizeof(a_) / sizeof(int) == 2); // OK
            static_assert(a_.size() > 1); // error: non-constant condition for static assertion. error: use of 'this' in a constant expression
            return a_[first ? 0 : 1];
        }
    };
    

    at compiler explorer

    更新 :看起来有点可疑,但可能不是因为下面的问题 link 演讲是关于运行时评估的,但是这里看起来像可以在编译时评估一个_.size()。

    更新2 更清晰的例子(考虑答案和评论后)

    #include <array>
    
    using Cont = std::array<int, 2>;
    
    // OK
    void checkSize(const Cont& b)
    {
        static_assert(b.size() == 2);
    }
    
    class A
    {
        Cont a_ = {};
    
    public:
        constexpr void checkSize() const
        {
            Cont b = {};
            static_assert(b.size() == 2); // OK
            static_assert(sizeof(a_) / sizeof(int) == 2); // OK
            static_assert(a_.size() == 2); // error: non-constant condition for static assertion. error: use of 'this' in a constant expression
        }
    };
    

    显示问题所在 这 参与评估 Ay.siz() . 但是为什么在那里需要它,而 阿尔 被编译器称为非虚拟类型和 尺寸() 可以在编译时评估,可能是另一个问题,所以我会检查第一个答案。

    2 回复  |  直到 8 年前
        1
  •  6
  •   Passer By    8 年前

    std::array::size ,即使是 constexpr 函数,不是 static 功能。这意味着它需要调用一个对象实例。

    在这种情况下, at 不是 常量表达式 阿西 因此 this 也不是,反过来 _a . 自从 γ-A 不是 常量表达式 的结果 _a.size() 不是 常量表达式 也是。

    即使是这样,尸体仍然 isn't considered constexpr .

        2
  •  3
  •   Clonk    8 年前

    a_ 是班上的一员 A .

    a_.size() 是一个简单的 this->a_.size() 因为大小不是静态函数,这意味着为了访问 阿尔 ,您必须访问 this .

    这 是指向类A的指针,而不是使 static_assert 失败了。

    使用模板可能更容易:

    template<int N>
    class B {
        std::array<int, N> a_;
        public:
        int& at(bool first)
        {
            static_assert((sizeof(a_) / sizeof(int)) == 2, "Sizeof operator"); // OK
            static_assert(N > 1, "Size method"); // No problem here
            return a_[first ? 0 : 1];
        }
    
    };