【问题标题】:How to declare a compile-time constant scope to a class within a local scope如何在本地范围内向类声明编译时常量范围
【发布时间】:2021-03-06 02:08:44
【问题描述】:

我在函数中定义了一个类。该类类型的对象稍后在函数中实例化,我想在该类中定义一个常量,该常量是从函数中引用的。

Live code

void foo() {
    class Internal {
    public:
        // here is the constant !!!
        static constexpr int NONE = std::numeric_limits<int>::max();
        // ------------------------
        Internal(int n = NONE) : _n(n) {}
        int get() const { return _n; }
    private:
        int _n;
    };
    
    Internal x(123), y;
    
    if (x.get() == Internal::NONE) {
       std::cout << "x" << std::endl; // not printed
    }
    if (y.get() == Internal::NONE) {
       std::cout << "y" << std::endl; // printed
    }
}

这会产生编译错误:

错误:本地类 'class foo()::Internal' 不应有静态数据成员 'constexpr const int foo()::Internal::NONE' [-fpermissive]

删除static,只留下constexpr,结果:

错误:非静态数据成员“NONE”声明为“constexpr”

仅使用 const 会导致:

错误:非静态数据成员'foo()::Internal::NONE'的使用无效

FWIW,static const 也不起作用。

除了将常量移出类范围之外,还有什么方法可以做到这一点?

【问题讨论】:

  • 期待后续问题,给出无法完成的答案:Why not?

标签: c++


【解决方案1】:

根据https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzarg/cplr062.htm

本地类不能有静态数据成员。在以下示例中,尝试定义本地类的静态成员会导致错误:

和 https://en.cppreference.com/w/cpp/language/class 在标题本地类下

本地类不能有静态数据成员

所以“除了将常量移出类范围之外,还有什么方法可以做到这一点?”

  • 没有。

【讨论】:

    【解决方案2】:

    不,静态 constexpr 成员被禁止使用本地类。可能是因为编译器实现它不是免费的,不像本地类。 (它的存储声明在哪里?什么时候初始化?等等。所有问题都可以回答,但正确回答这些问题是有代价的)。

     static constexpr int NONE(){ return std::numeric_limits<int>::max(); }
    

    不过,这行得通。

    【讨论】:

    • 接受了这个(尽管其他的在技术上是正确的),因为它通过稍微调整问题来遵循我想要的精神。我可以使用static constexpr 方法,而不是使用常量。谢谢!
    【解决方案3】:

    除了将常量移出类范围之外,还有什么方法可以做到这一点?

    当然。实现此目的的另一种方法是将类移出块范围。

    【讨论】:

      猜你喜欢
      • 2015-05-26
      • 2017-02-27
      • 2016-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多