Posso ottenere un compilatore C ++ per istanziare oggetti in fase di compilazione

5

Sto scrivendo un codice che ha un numero molto grande di oggetti ragionevolmente semplici e vorrei che fossero creati in fase di compilazione. Penserei che un compilatore sarebbe in grado di farlo, ma non sono stato in grado di capire come.

In C potrei fare quanto segue:

#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);
   }
}

Usando #C ++ * ogni oggetto ha chiamato il costruttore piuttosto che essere semplicemente messo in memoria.

#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;
    }
}

Semplicemente non vedo quali informazioni non sono disponibili per il compilatore per istanziare completamente questi oggetti in fase di compilazione, quindi presumo che mi manchi qualcosa.

    
posta gam3 16.09.2012 - 00:10
fonte

6 risposte

6

In C ++ 11 puoi usare un costruttore di constexpr come questo:

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"),
};

GCC 4.7.1 in modalità C ++ 0x supporta i costruttori di constexpr in fase di compilazione, e il codice sopra funziona come desiderato, senza chiamate al costruttore Info nel codice generato.

Si noti che il compilatore non è obbligato a fare una costruzione completa in fase di compilazione - in linea di principio potrebbe posticipare la costruzione al runtime.

    
risposta data 17.09.2012 - 22:01
fonte
3

Se vuoi tutte quelle cose extra lì dentro, bene - dovrai istanziarle esplicitamente.

Ma non c'è niente che ti impedisca di usare il modo C per i tuoi oggetti, ma li costruisco e li trattano come strutture POC. Il C ++ è compatibile all'indietro. In alternativa, posiziona una struct all'interno della classe come variabile membro e crea un'istanza di tale.

Con C ++ 11 puoi usare gli elenchi di inizializzatori per costruire il tuo oggetto, come per questo SO rispondere

    
risposta data 16.09.2012 - 14:19
fonte
2

Sei un hosed. I problemi sono quei membri di dati privati const e il costruttore. Ciò rende la tua classe una classe non aggregata. L'unico modo per costruire un oggetto Info è chiamando il costruttore e il compilatore non lo fa.

    
risposta data 16.09.2012 - 09:08
fonte
1

Chi dice che il compilatore non sta facendo esattamente quello che vuoi? Nel codice mostrato, un compilatore conforme può compilare il tuo codice List nello stesso assembly del codice C.

    
risposta data 17.09.2012 - 15:32
fonte
0

Probabilmente non ti sarà di grande aiuto, ma ti suggerisco di esaminare la meta-programmazione dei modelli. :-)

    
risposta data 16.09.2012 - 15:21
fonte
-1

Non puoi davvero crearli in fase di compilazione, ma puoi ingannare il compilatore specificando la creazione di strutture di dati piuttosto complesse usando le macro per memorizzare le informazioni, e poi usando più definizioni diverse della macro per depositare le informazioni secondo necessità .

Ad esempio, puoi avere una struttura macro come

in un file di intestazione "header.h":

foo(x,1) 
foo(y,2)

quindi in un posto

#define foo(a,b) a = b;
#include "header.h"
#undef foo

e in un altro posto

#define foo(a,b) #a,

char *name = {
#include "header.h"
};
#undef foo

e così via

    
risposta data 16.09.2012 - 21:47
fonte

Leggi altre domande sui tag