gpt4 book ai didi

c++ - 为什么这个 constexpr 静态成员函数在调用时不被视为 constexpr?

转载 作者:IT老高 更新时间:2023-10-28 22:28:20 26 4
gpt4 key购买 nike

为什么这个constexpr static成员函数,由//!标识Nah 注释,调用时不被视为 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
}

MinGW 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 constantconstexpr.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'

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

这似乎与不完整的类有关,因为定义了 OUT_OF_CLASS 它可以很好地编译。

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

最佳答案

从内存中,成员函数体只有在类被完全定义后才会被评估。

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
}

Why do you think the standard disallows it?

因为这是非法的:

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++ - 为什么这个 constexpr 静态成员函数在调用时不被视为 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37194245/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com