Constexpr成员函数 [英] Constexpr member function

查看:176
本文介绍了Constexpr成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose I have a struct template S that is parametrized by an engine:

template<class Engine> struct S;

我有两个引擎:一个带有 constexpr的静态引擎成员函数 size(),以及一个带有非 constexpr 成员函数的动态变量 size()

I have two engines: a "static" one with a constexpr member function size(), and a "dynamic" one with a non-constexpr member function 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;
};

我想定义 size()成员 S 中的函数,如果引擎的 size()可以用作 constexpr code>是 constexpr 。我写道:

I want to define size() member function in S that can be used as a constexpr if the engine's size() is constexpr. I write:

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

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

Then the following code compiles with GCC, Clang, MSVC and ICC:

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

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

考虑到 constexpr 的复杂性格式错误,不需要诊断,我仍然有一个问题:此代码格式正确吗?

Taking into account intricacies of constexpr and various "ill-formed, no diagnostic is required", I still have the question: is this code well-formed?

Godbolt.org上的完整代码

(我用这两种标准的有效性不同。)

(I tagged this question with both c++17 and c++20 in case this code has different validity in these two standards.)

推荐答案

代码写得很好。


[dcl.constexpr]

6 如果constexpr
函数模板的实例化模板特化类模板的成员函数将无法使
满足constexpr函数或constexpr
构造函数的要求,即,专业化仍然是constexpr函数或
constexpr构造函数,即使对此类调用函数
不能出现在常量表达式中。如果模板
的任何专业化都不能满足constexpr函数或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 是一个很好的例子。

The member may not appear in a constant expression for the specialization that uses Dynamic_engine, but as the paragraph above details, that does not make S::size ill-formed. We are also far from ill-formed NDR territory, since valid instantations are possible. Static_engine being a prime example.

引号来自最新的C ++ 17标准草案n4659,以及类似的措词出现在最新的C ++ 20草案中。

The quote is from n4659, the last C++17 standard draft, and similar wording appears in the latest C++20 draft.

对于 sta的评估.size()作为常量表达式,在 [expr.const] 我找不到评估本身不允许的任何内容。因此,它是一个有效的常量表达式(因为该列表告诉我们无效无效)。通常,为了使 constexpr 函数有效,只需要存在 some 个参数集,就可以为其生成有效的常量表达式。如以下示例表格中的标准所示:

As for the evaluation of sta.size() as a constant expression, going over the list at [expr.const] I cannot find anything that is disallowed in the evaluation itself. It is therefore a valid constant expression (because the list tells us what isn't valid). And in general for a constexpr function to be valid, there just needs to exist some set of arguments for which the evaluation produces a valid constant expression. As the following example form the standard illustrates:

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
};

这篇关于Constexpr成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆