Constexpr成员函数

问题描述 投票:1回答:2

假设我有一个由引擎参数化的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;
};

我想在size()中定义S成员函数,如果引擎的constexprsize(),则可以用作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

((如果此代码在这两个标准中具有不同的有效性,我会同时用标记这个问题。]

c++ c++17 constexpr c++20
2个回答
3
投票

代码写得很好。

[dcl.constexpr]

6如果constexpr的实例化模板特化函数模板或类模板的成员函数将无法满足constexpr函数或constexpr的要求构造函数,该专业化仍然是constexpr函数或constexpr构造函数,即使不能调用此类函数以常量表达式出现。如果没有专业化的模板将满足constexpr函数或constexpr的要求构造函数,当被视为非模板函数或构造函数时,模板格式错误,无需诊断。

对于使用Dynamic_engine的专业化,该成员可能不会出现在常量表达式中,但是如上面的段落所述,这不会使S::size格式错误。我们也远离格式错误的NDR领土,因为有效的实例是可能的。 Static_engine是一个很好的例子。引号来自最新的C ++ 17标准草案n4659,最新的C ++ 20草案中出现了类似的措词。


1
投票
© www.soinside.com 2019 - 2024. All rights reserved.