我可以在编译时使用C++编译器来实例化对象吗?

G. *_*III 3 c++ optimization gcc

我正在编写一些具有大量相当简单的对象的代码,我希望它们可以在编译时创建.我认为编译器能够做到这一点,但我无法弄清楚如何.

C中,我可以执行以下操作:

#include <stdio.h>

typedef struct data_s {
    int a;
    int b;
    char *c;
} info;

info list[] = {
    1, 2, "a",
    3, 4, "b",
};

main()
{
   int i;
   for (i = 0; i < sizeof(list)/sizeof(*list); i++) {
     printf("%d %s\n", i, list[i].c);
   }
}
Run Code Online (Sandbox Code Playgroud)

使用#C++*每个对象都有一个被调用的构造函数,而不仅仅是在内存中进行布局.

#include <iostream>
using std::cout;
using std::endl;

class Info {
    const int a;
    const int b;
    const char *c;
public:
    Info(const int, const int, const char *);
    const int get_a() { return a; };
    const int get_b() { return b; };
    const char *get_c() const { return c; };
};

Info::Info(const int a, const int b, const char *c) : a(a), b(b), c(c) {};

Info list[] = {
    Info(1, 2, "a"),
    Info(3, 4, "b"),
};

main()
{
    for (int i = 0; i < sizeof(list)/sizeof(*list); i++) {
        cout << i << " " << list[i].get_c() << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我只是没有看到编译器没有哪些信息可以在编译时完全实例化这些对象,所以我假设我遗漏了一些东西.

Die*_*ühl 6

在C++ 2011中,您可以在编译时创建对象.为此,您需要使各种事物成为常量表达式,但是:

  1. 需要声明构造函数constexpr.
  2. 您声明的实体需要声明constexpr.

请注意,几乎所有const限定符都不相关或位置错误.下面是一个带有各种修正的示例,并且实际上还演示了list在编译期间对数组进行初始化(通过使用它的成员来定义a的值enum):

#include <iostream>
#include <iterator>

class Info {
    int a;
    int b;
    char const*c;

public:
    constexpr Info(int, int, char const*);
    constexpr int get_a() const { return a; }
    constexpr int get_b() const { return b; }
    constexpr char const*get_c() const { return c; }
};

constexpr Info::Info(int a, int b, char const*c)
  : a(a), b(b), c(c) {}

constexpr Info list[] = {
    Info(1, 2, "a"),
    Info(3, 4, "b"),
};

enum {
    b0 = list[0].get_b(),
    b1 = list[1].get_b()
};

int main()
{
    std::cout << "b0=" << b0 << " b1=" << b1 << "\n";
    for (Info const* it(list), *end(list); it != end; ++it) {
        std::cout << (it - list) << " " << it->get_c() << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)