Встроенное определение таблицы C на C ++ - PullRequest
0 голосов
/ 29 мая 2018

У меня есть код на C, который компилируется и работает правильно, и я хотел бы использовать подобный код на 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;
}

Теперь, если я положу его в файл .c и скомпилирует с gccоно работает.Но, если я помещаю его в файл .cpp и компилирую его с g++, я получаю следующие ошибки:

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]

Есть ли способ выразить, что я не объявляюлямбда-функция, просто пытающаяся заполнить таблицу?

Я хотел бы сохранить следующую часть:

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

, потому что она происходит из автоматически сгенерированного файла ...

Ответы [ 5 ]

0 голосов
/ 29 мая 2018

Как было сказано выше, этот тип инициализации не поддерживается в C ++, но вы можете использовать лямбда-функцию для инициализации static array<const char*, 12>, например:

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

Демонстрация на coliru

Следует отметить, что компилятор здесь выполнит RVO , и инициализация будет выполнена на месте.Это сборка, сгенерированная 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   
0 голосов
/ 29 мая 2018

Обозначенные инициализаторы, не поддерживаемые C ++, уже упоминались - если вы настаиваете на C ++, вы могли бы вместо этого написать класс-оболочку с конструктором:

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;

Не тестировал код, поэтому, если вы найдетеошибка, не стесняйтесь исправить это самостоятельно ...

0 голосов
/ 29 мая 2018

[4]= - это обозначенный инициализатор , одна из функций C, не поддерживаемых C ++.

Вот список , который пытается перечислить, какие функции C99 поддерживаются C ++ 17.Прокрутите вниз, чтобы увидеть, какие из них не поддерживаются.

Важно понимать, что C ++ ни в коем случае не является надмножеством C.

0 голосов
/ 29 мая 2018

Вы можете легко смешивать код C и C ++.

Вы должны сохранять код C для компиляции с помощью компилятора C (gcc), остальная часть кода может быть C ++ и компилироваться с помощью компилятора C ++ (g ++),затем свяжите все файлы объектов (.o) вместе.

примерно так:

имя файла: ac

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

имя файла: b.cpp

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

Теперь скомпилируйте:

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

Теперь запустите исполняемый файл (all.out), и вы увидите, что все будет работать.

Просто обратите внимание, что для функций вам нужно добавить extern "C" перед объявлением в файле cpp.

0 голосов
/ 29 мая 2018

Нет способа сделать это.C ++ никогда не принимал этот конкретный синтаксис C.

В вашем случае, поскольку таблица генерируется автоматически, я бы просто поместил ее в файл C.Пока он не помечен static, к нему можно получить доступ из кода C ++ без проблем.

...