c++ - 在 C++ 的编译期间成员函数是否可用?

标签 c++ c++11 compilation constexpr

尝试使用 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。

https://godbolt.org/z/P2fcfK

#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/

相关文章:

objective-c - objective c linux 编译脚本

c - 我应该如何编译这个C代码?

c++ - 自定义 QWidget 不继承父样式表

c++ - 显式关键字应用于运算符而不是构造函数

c++ - std::将 std::unique_ptr 移动到 STL 容器中。 (MSVC编译器问题)

c++ - std::integral_constant<bool> 的否定

c++ - 带有英特尔 MKL 多线程的 Rcpp

c++ - Qt 正在获取对 YouTube api 的请求,不支持 utf8 字符

c++ - 我可以向编译器查询 C++0x "alignas"支持吗?

c++ - 是否可以在编译时获取时间(当天)和日期?