当前位置: 首页 > 知识库问答 >
问题:

为什么在调用时,这个Constexr静态成员函数没有被视为Constexr?

施学
2023-03-14

为什么这个 constexpr 静态成员函数,由 // 标识!没有评论,当打电话时不被视为 constexpr

struct Item_id
{
    enum Enum
    {
        size, position, attributes, window_rect, max_window_size, _
    };

    static constexpr int n_items_ = _;                          // OK
    constexpr auto member_n_items() const -> int { return _; }  // OK
    static constexpr auto static_n_items() -> int { return _; } // OK
    static constexpr int so_far = n_items_;                     // OK
    #ifndef OUT_OF_CLASS
        static constexpr int bah = static_n_items();            //! Nah.
    #endif
};

constexpr auto n_ids() -> int { return Item_id().member_n_items(); }    // OK

auto main() -> int
{
    #ifdef OUT_OF_CLASS
        static constexpr int bah = Item_id::static_n_items();   // OK
    #endif
}

明吉瓦 g 5.1 报告

constexpr.cpp:12:46: error: 'static constexpr int Item_id::static_n_items()' called in a constant expression
     static constexpr int bah = static_n_items();                //! Nah.

Visual C 2015 报告

constexpr.cpp(12): error C2131: expression did not evaluate to a constant
constexpr.cpp(12): note: failure was caused by call of undefined function or one not declared 'constexpr'
constexpr.cpp(12): note: see usage of 'Item_id::static_n_items'

我的文本编辑器坚持调用中的名称与函数定义中的名称相同。

这似乎与不完整的类有关,因为通过定义< code>OUT_OF_CLASS,它可以很好地编译

但是,为什么< code>n_items_数据有效,为什么这样的规则(对我来说没有意义)?

共有2个答案

能旭
2023-03-14

[class.mem]/2

在类成员规范中,类在函数体、默认参数、异常规范和默认成员初始化器(包括嵌套类中的这些东西)中被认为是完整的。否则,在它自己的类成员规范中,它被认为是不完整的。

在类的< code>static数据成员的初始值设定项中,该类不完整。初始化器只能看到它前面成员的声明,它能看到的任何成员函数都被认为是已声明的,而不是已定义的。对已声明但未定义的函数的调用不能是常量表达式。

梁宪
2023-03-14

根据记忆,只有在类被完全定义后,才会评估成员函数体。

static constexpr int bah = static_n_items(); 

构成类定义的一部分,但它指的是尚未定义的(静态)成员函数。

解决方案:

将常量表达式延迟到基类并从其派生。

例如:

struct Item_id_base
{
    enum Enum
    {
        size, position, attributes, window_rect, max_window_size, _
    };

    static constexpr int n_items_ = _;                          // OK
    constexpr auto member_n_items() const -> int { return _; }  // OK
    static constexpr auto static_n_items() -> int { return _; } // OK
    static constexpr int so_far = n_items_;                     // OK
};

struct Item_id : Item_id_base
{
    #ifndef OUT_OF_CLASS
        static constexpr int bah = static_n_items();            // now OK
    #endif
};

constexpr auto n_ids() -> int { return Item_id().member_n_items(); }    // OK

auto main() -> int
{
    #ifdef OUT_OF_CLASS
        static constexpr int bah = Item_id::static_n_items();   // OK
    #endif
}

为什么你认为标准不允许它?

因为这是非法的:

struct Item_id
{   
    // ... etc.

    #ifndef OUT_OF_CLASS
        static constexpr int bah;// = static_n_items();            //! Nah.
    #endif
};

constexpr int Item_id::bah = static_n_items();

constexpr必须具有constexpr定义。我们唯一能定义它的地方是在它的声明中。。。

...因此,通过演绎,它不能指任何尚未定义身体的功能。

我不知道在哪里寻找所有这些标准。可能有 5 个不同的、看似无关的条款:)

 类似资料:
  • 本文向大家介绍在一个静态方法内调用一个非静态成员为什么是非法的?相关面试题,主要包含被问及在一个静态方法内调用一个非静态成员为什么是非法的?时的应答技巧和注意事项,需要的朋友参考一下 由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。

  • 我想知道为什么C中的函数重载解析在调用静态方法时会考虑非静态成员函数。 我已经阅读了这里的文档,其中指出 如果任何候选函数是成员函数(静态或非静态),但不是构造函数,则将其视为具有额外参数(隐式对象参数),该参数表示调用它们的对象并出现在第一个之前实际参数。 因此,请考虑以下代码。 那么调用A::foo(1.f,1.f)是不明确的。 静态成员函数用于非静态函数调用的重载解析,这很有意义。 但是为什

  • 我正在学习Java,正在使用java 8,spring 5.3.9和Apache Tomcat 9。我已经将我的jar文件添加到我的构建路径中的类路径中,将Apache Tomcat添加到我的服务器中,我的项目运行得非常好。现在我开始使用beans和xml文件,我遇到了一个问题。我的代码的一部分被触发,另一部分被忽略。 我有以下界面 FortuneService.java: 和一个快乐财富服务类:

  • 本文向大家介绍什么是C#中的静态成员函数?,包括了什么是C#中的静态成员函数?的使用技巧和注意事项,需要的朋友参考一下 静态函数只能访问静态变量。静态函数甚至在创建对象之前就已存在。 将静态函数设置为- 以下是演示静态函数用法的示例- 示例 输出结果

  • 这是有效代码: 但是在这里,我真的很想声明和 。但是为什么呢?

  • 问题内容: 另外,在网上可以找到许多创建静态变量的解决方案。(尽管我还没有看到我喜欢的一个。) 为什么Python不支持方法中的静态变量?这被认为是非Python的,还是与Python的语法有关? 编辑: 我专门询问了 为什么 进行设计决策,但我没有提供任何代码示例,因为我想避免解释来模拟静态变量。 问题答案: 忽略这一点的想法是,静态变量仅在以下两种情况下才有用:何时真正应该使用类以及何时真正应