web-dev-qa-db-ja.com

C ++コンパイラでコンパイル時にオブジェクトをインスタンス化できますか

かなり単純なオブジェクトが非常に多いコードをいくつか書いていますが、それらをコンパイル時に作成してもらいたいのです。私はコンパイラーがこれを行うことができると思いますが、私はその方法を理解することができませんでした。

[〜#〜] 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;
    }
}

コンパイラがこれらのオブジェクトをコンパイル時に完全にインスタンス化するために利用できない情報がないので、何か不足していると思います。

6
gam3

C++ 11では、次のようにconstexprコンストラクターを使用できます。

class Info {
    const int a;
    const int b;
    const char *c;
public:
    constexpr 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; }
};

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

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

C++ 0xモードのGCC 4.7.1はコンパイル時にconstexprコンストラクターをサポートし、上記のコードは必要に応じて機能しますが、生成されたコードでInfoコンストラクターを呼び出す必要はありません。

コンパイラーはコンパイル時に完全な構築を行う必要がないことに注意してください-原則的には、構築を実行時に延期することができます。

6
han

そこに余分なものをすべて入れたいのであれば、結構です-それらを明示的にインスタンス化する必要があります。

しかし、オブジェクトに対してCの方法を使用することを妨げるものは何もありません。それらをPOC構造体として作成して処理するだけです。 C++は下位互換性があります。または、クラス内に構造体をメンバー変数として配置し、インスタンス化します。

C++ 11では、イニシャライザリストを使用してオブジェクトを構築できます this SO answer

3
gbjbaanb

あなたはうんざりしています。問題は、それらのconstプライベートデータメンバーとコンストラクターです。これらはあなたのクラスを非集合クラスにします。 Infoオブジェクトを構築する唯一の方法は、コンストラクターを呼び出すことであり、コンパイラーはそれを行いません。

2
David Hammen

コンパイラはあなたが望んでいることを正確に行っていないと誰が言っていますか?ここに示すコードでは、準拠コンパイラがListコードをCコードと同じアセンブリにコンパイルする場合があります。

1
MSalters

これはおそらくあまり役​​に立ちませんが、テンプレートメタプログラミングを検討することをお勧めします。 :-)

0
alvonellos