c++ - 不使用这个的 constexpr 成员函数?

标签 c++ c++14 language-lawyer constexpr

请考虑以下两个 C++14 程序:

程序 1:

struct S { constexpr int f() const { return 42; } };
S s;
int main() { constexpr int x = s.f(); return x; }

程序 2:

struct S { constexpr int f() const { return 42; } };
int g(S s) { constexpr int x = s.f(); return x; }
int main() { S s; return g(s); }

这些程序中的一个或两个都不是良构的吗?

为什么/为什么不?

最佳答案

这两个程序都是良构的。 C++14 标准要求 s.f() 是一个常量表达式,因为它被用来初始化一个 constexpr 变量,事实上它是一个核心常量表达式,因为没有理由不这样。表达式可能不是核心常量表达式的原因在第 5.19 节 p2 中列出。特别是,它指出表达式的求值必须做几件事中的一件,而您的示例中没有做任何一件事情。

这可能令人惊讶,因为在某些情况下,将非常量表达式传递给 constexpr 函数可能会导致结果成为非常量表达式,即使未使用参数也是如此。例如:

constexpr int f(int) { return 42; }

int main()
{
    int x = 5;
    constexpr auto y = f(x); // ill-formed
}

然而,这是错误格式的原因是因为非常量表达式的左值到右值转换,这是表达式的求值不是的事情之一允许做。调用 s.f() 时不会发生左值到右值的转换。

关于c++ - 不使用这个的 constexpr 成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32803708/

相关文章:

java - Java 中的 FINAL 变量保存两个不同的值

c++ - 使用 CRTP 进行模拟类

c++ - C++14 中通用 lambda 函数的递归

c++ - 循环模板类型

c++ - 是否可以给枚举类枚举器起别名?

c++ - 是否有关于诸如 erase/remove_if 之类的算法以及 remove_if 实现的可能副作用的编程标准?

c++ - 是否存在使用 "__attribute__((warn_unused_result))"不起作用的条件?

C++11 std::atomic<T> 复制构造函数的线程安全

c++ - 将具有 unique_ptr 的类的构造函数作为成员复制到抽象类

c++ - 我应该如何有条件地启用构造函数?