我能否在编译时获得一个 C++ 编译器来实例化对象?

3
我正在编写一些代码,其中包含大量相对简单的对象,并希望它们在编译时创建。我认为编译器应该能够做到这一点,但我还没有找出如何实现。
在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);
   }
}

使用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;
    }
}

我只是不明白编译器在编译时没有完全实例化这些对象需要哪些信息,所以我认为我可能遗漏了什么。


看看静态类或单例模式。也许这就是你在C++中寻找的东西。 - Najzero
5
你在Programmers上得到的答案有什么问题? - DCoder
@Najzero C++ 没有静态类。 - juanchopanza
@DCoder:我的回答是:“C++ 方式尚未提及”。当然,这假设作者打错了标题,因为实际问题明确使用的是 C++ 而不是 C。 - Dietmar Kühl
1个回答

9
在C++ 2011中,你可以在编译时创建对象。为了实现这一点,你需要使各种东西成为常量表达式,但是需要注意以下几点:
  1. 构造函数需要被声明为constexpr
  2. 你所声明的实体需要被声明为constexpr
请注意,几乎所有的const限定符都是不相关或放置位置错误的。以下是一个示例,演示了各种修正,并且实际上演示了在编译时初始化list数组(通过使用其中的成员定义一个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";
    }
}

constexpr get_a合法,难道不需要将ab声明为const吗?或者说constexpr对象可以是可修改的(我知道它们是私有的,但如果我在Info对象上分配给a会发生什么?” - ted
@ted:成员不需要是“constexpr”,因为整个对象都是“constexpr”。如果您想从非'const'对象中获取一个“constexpr”,但访问成员,则该成员需要是“constexpr”(当然,还有其他定义该成员的各种内容)。 - Dietmar Kühl
谢谢您的解释。您在写“but”时是指“by”吗? - ted
啊,是的:应该是“按照”而不是“通过”。 - Dietmar Kühl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接