web-dev-qa-db-fra.com

Définition en ligne de table C vers C ++

J'ai du code en C qui se compile et fonctionne correctement et je voudrais utiliser un code similaire en C++:

static const char* aTable[12] = {
    [4]="seems",
    [6]=" it  ",
[8]="works",};

int main(){
    printf("%s%s%s", aTable[4],aTable[6],aTable[8]); 
    return 0;
}

Maintenant, si je le mets dans un .c fichier et compile avec gcc ça marche. Mais si je le mets dans un .cpp fichier et compilez-le avec g++, J'obtiens les erreurs suivantes:

test_cpp.cpp:5:3: error: expected identifier before numeric constant
test_cpp.cpp:5:4: error: type '<lambda>' with no linkage used to declare function 'void<lambda>::operator()() const' with linkage [-fpermissive] 
test_cpp.cpp: In lambda function: test_cpp.cpp:5:5: error: expected '{' before '=' token 
test_cpp.cpp: At global scope: test_cpp.cpp:5:5: warning: lambda expressions only available with
    -std=c++0x or -std=gnu++0x [enabled by default] 
test_cpp.cpp:5:6: error: no match for 'operator=' in '{} = "seems"' test_cpp.cpp:5:6: note: candidate is: test_cpp.cpp:5:4: note: <lambda()>&<lambda()>::operator=(const<lambda()>&) 
test_cpp.cpp:5:4: note:   no known conversion for argument 1 from 'const char [6]' to 'const<lambda()>&' 
test_cpp.cpp:6:3: error: expected identifier before numeric constant
test_cpp.cpp:6:4: error: type '<lambda>' with no linkage used to declare function 'void<lambda>::operator()() const' with linkage [-fpermissive]

Existe-t-il un moyen d'exprimer que je ne déclare pas une fonction lambda, juste en essayant de remplir un tableau?

Je voudrais garder la partie suivante:

[4]="seems",
[6]=" it  ",
[8]="works",

car il provient d'un fichier généré automatiquement ...

41
Aname

Vous pouvez facilement mélanger du code C et C++.

Vous devez conserver le code C à compiler avec le compilateur C (gcc), le reste du code peut être C++ et être compilé avec le compilateur C++ (g ++). puis liez tous les fichiers objet (.o) ensemble.

comme ça:

nom de fichier: a.c

const char* aTable[12] = {
    [4]="seems",
    [6]=" it  ",
[8]="works",};

nom de fichier: b.cpp

#include <cstdio>
extern "C" const char* aTable[12];   
int main(){
    printf("%s%s%s", aTable[4],aTable[6],aTable[8]); 
    return 0;
}

Compilez maintenant:

gcc -c a.c -o a.o
g++ -c b.cpp -o b.o
g++ b.o a.o -o all.out

Exécutez maintenant l'exécutable (all.out) et vous verrez que tout fonctionnera.

Notez simplement que pour les fonctions, vous devrez ajouter extern "C" avant la déclaration dans le fichier cpp.

28
SHR

Il n'y a aucun moyen de le faire. C++ n'a jamais adopté cette syntaxe C particulière.

Dans votre cas, comme la table est générée automatiquement, je la mettrais simplement dans un fichier C. Tant qu'il n'est pas marqué static, il est accessible sans problème à partir du code C++.

16
user743382

[4]= est un initialiseur désigné , l'une des fonctionnalités C non prise en charge par C++.

Voici un list qui essaie de répertorier les fonctionnalités C99 prises en charge par C++ 17. Faites défiler vers le bas pour voir ceux qui ne sont pas pris en charge.

Il est important de réaliser que C++ n'est en aucun cas un surensemble de C.

13
Lundin

Les initialiseurs désignés ne sont pas pris en charge par C++ déjà mentionnés - si vous insistez sur C++, vous pouvez écrire une classe wrapper avec un constructeur à la place:

class Table
{
    std::array<char const*, 12> data;
public:
    Table()
    {
        data[4] = "seems";
        data[6] = " it  ";
        data[8] = "works";
    }
    char const* operator[](unsigned int index) const
    {
        return data[index];
    }
} aTable;

Je n'ai pas testé le code, donc si vous trouvez un bug, n'hésitez pas à le corriger vous-même ...

5
Aconcagua

Comme indiqué ci-dessus, ce type d'initialisation n'est pas pris en charge en C++, mais vous pouvez utiliser la fonction lambda pour initialiser static array<const char*, 12> comme ça:

#include <array>
#include <cstdio>

static const std::array<const char*, 6> aTable = []() {
    std::array<const char*, 6> table;
    table[0] = "Hello";
    table[3] = ", ";
    table[5] = "world!";
    return std::move(table);
}();

int main() {
    printf("%s%s%s\n", aTable[0], aTable[3], aTable[5]);
    return 0;
}

Demo on colir

Notable, ce compilateur fera RVO ici, et l'initialisation sera effectuée sur place. C'est l'assembly généré par g ++ - 5.4.0:

<_GLOBAL__sub_I_main>:
movq   $0x40064c,0x200bc5(%rip)        # 601060 <_ZL6aTable>
movq   $0x400652,0x200bd2(%rip)        # 601078 <_ZL6aTable+0x18>
movq   $0x400655,0x200bd7(%rip)        # 601088 <_ZL6aTable+0x28>
retq   
2
ivaigult