gpt4 book ai didi

c++ - Constexpr 成员函数

转载 作者:行者123 更新时间:2023-12-01 22:37:31 25 4
gpt4 key购买 nike

假设我有一个由引擎参数化的 struct 模板 S:

template<class Engine> struct S;

我有两个引擎:一个是带有 constexpr 成员函数 size() 的“静态”引擎,另一个是带有非 constexpr 的“动态”引擎 成员函数size():

struct Static_engine {
static constexpr std::size_t size() {
return 11;
}
};

struct Dynamic_engine {
std::size_t size() const {
return size_;
}
std::size_t size_ = 22;
};

我想在 S 中定义 size() 成员函数,如果引擎的 size( )constexpr。我写道:

template<class Engine>
struct S {
constexpr std::size_t size() const {
return engine_.size();
}
Engine engine_;
};

然后使用 GCC、Clang、MSVC 和 ICC 编译以下代码:

S<Static_engine> sta;         // not constexpr
S<Dynamic_engine> dyn;

constexpr auto size_sta = sta.size();
const auto size_dyn = dyn.size();

考虑到 constexpr 的复杂性和各种“格式错误,无需诊断”,我仍然有一个问题:这段代码格式正确吗?

Full code on Godbolt.org

(我用 标记了这个问题,以防该代码在这两个标准中具有不同的有效性。)

最佳答案

代码写得很好。

[dcl.constexpr]

6 If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.

该成员可能不会出现在使用 Dynamic_engine 的专门化的常量表达式中,但正如上面段落详细说明的那样,这不会使 S::size 生病 -形成。我们也远离格式错误的 NDR 领域,因为有效的实例是可能的。 Static_engine 就是一个很好的例子。

该引用来自最新的 C++17 标准草案 n4659,类似的措辞也出现在最新的 C++20 草案中。

<小时/>

至于将 sta.size() 作为常量表达式进行计算,请查看 [expr.const] 处的列表。我找不到评估本身不允许的任何内容。因此,它是一个有效的常量表达式(因为该列表告诉我们什么无效)。一般来说,要使 constexpr 函数有效,只需要存在一些参数集,计算即可为其生成有效的常量表达式。正如以下标准示例所示:

constexpr int f(bool b)
{ return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required

struct B {
constexpr B(int x) : i(0) { } // x is unused
int i;
};

int global;

struct D : B {
constexpr D() : B(global) { } // ill-formed, no diagnostic required
// lvalue-to-rvalue conversion on non-constant global
};

关于c++ - Constexpr 成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58866631/

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