尝试使用 c++11 标准(使用 constexpr)编译以下内容成功完成:
class test{
public:
int getId(){
constexpr int id = 5;
return id;
}
};
在编译期间,test
还不存在,但是上面的代码编译正常。
如果 test
还不存在,那么 getId
如何在编译期间存在?
完整的工作示例:
#include <iostream>
class test{
public:
int getId(){
constexpr int id = 5;
return id;
}
};
int main(){
test t;
std::cout << t.getId() << std::endl;
return 0;
}
最佳答案
您可以将成员函数用作constexpr,但必须将其声明为constexpr。
#include <iostream>
class test{
public:
constexpr int getId(){
constexpr int id = 5;
return id;
}
};
int main()
{
constexpr int G = test().getId();
std::cout << G << std::endl;
return 0;
}
/edit 这是您发布的代码....
#include <iostream>
class test{
public:
int getId(){ //< this method is NOT constexpr
constexpr int id = 5; //< id is constexpr, and it's the only constexpr here.
return id;
}
};
int main(){
test t; //< this cannot be constexpr because it's a variable
//< (which means it is NOT an expression!)
std::cout << t.getId() << std::endl;
return 0;
}
\编辑2 这是可以在编译时求值的最简单的表达式:
constexpr int id = 5;
这是一个稍微有趣一点的表达
constexpr int id = 5 * 5 + 22 / 11 - 9 * 65;
在那种情况下,可以在编译时计算表达式。这是一个不能在编译时求值的例子:
int var(int a) {
constexpr int id = 5 * a; //< invalid! a is not constexpr!
return id;
}
getId() 在这里不能是 constexpr,因为我们需要将它声明为 constexpr,但是天真的方法会失败:
constexpr int var(const int a) {
constexpr int id = 5 * a; //< invalid! a is not constexpr!
return id;
}
它失败了,因为我们在第二个表达式中使用了变量“a”。但是,这会起作用(我们删除了第二个表达式,并将其折叠回单个表达式)
constexpr int var(const int a) {
return 5 * a;
}
constexpr int foo = var(22); //< will be evaluated at compile time.
现在我们可以使用成员变量和构造函数来完成此操作,但我们需要确保构造函数是 constexpr。例如:
#include <iostream>
struct Dave
{
const int a;
constexpr Dave(const int b) : a(b) {}
constexpr int var() const {
return 5 * a;
}
};
int main()
{
constexpr int c = Dave(22).var();
return c;
}
现在查看 godbolt:https://godbolt.org/z/4naDY3 我们可以看到 main 的代码归结为:
main:
mov eax, 110
ret
因此它在编译时计算了 5 * 22,即 110。您可能不喜欢 constexpr 规则的工作方式(它们有点笨拙),但 constexpr 确实有效。
关于c++ - 在 C++ 的编译期间成员函数是否可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59241521/