C в C++ встроенное определение таблицы
У меня есть код на 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",
потому что это происходит из автогенерируемого файла...
Ответы
Ответ 1
Вы можете легко смешивать код 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.
Ответ 2
Нет никакого способа сделать это. C++ никогда не принимал этот особый синтаксис Си.
В вашем случае, поскольку таблица автоматически сгенерирована, я бы просто поместил ее в файл C. Пока он не помечен как static
, его можно получить из кода C++ без проблем.
Ответ 3
[4]=
- назначенный инициализатор, одна из функций C, не поддерживаемая C++.
Вот список, который пытается указать, какие функции C99 поддерживаются C++ 17. Прокрутите страницу вниз, чтобы увидеть, какие из них не поддерживаются.
Важно понимать, что C++ никоим образом не является надмножеством C.
Ответ 4
Назначенные инициализаторы, которые не поддерживаются 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;
Не тестировал код, поэтому, если вы обнаружите ошибку, не стесняйтесь исправить ее самостоятельно...
Ответ 5
Как было сказано выше, этот тип инициализации не поддерживается в 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;
}
Demo on 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