web-dev-qa-db-ja.com

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",

それは自動生成されたファイルから来ているので...

41
Aname

CコードとC++コードを簡単に混在させることができます。

CコードはCコンパイラ(gcc)でコンパイルする必要があります。残りのコードはC++で、C++コンパイラ(g ++)でコンパイルできます。次に、すべてのオブジェクト(.o)ファイルをリンクします。

このような:

ファイル名:a.c

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)を実行すると、すべてが機能することがわかります。

関数については、cppファイルの宣言の前にextern "C"を追加する必要があることに注意してください。

28
SHR

これを行う方法はありません。 C++はこの特定のC構文を採用していません。

あなたの場合、テーブルは自動生成されるので、Cファイルに入れるだけです。 staticとマークされていない限り、C++コードから問題なくアクセスできます。

16
user743382

[4]=は、指定イニシャライザであり、C++でサポートされていないC機能の1つです。

C++ 17でサポートされているC99機能をリストしようとする list があります。下にスクロールして、サポートされていないものを確認します。

C++は決してCのスーパーセットではないことを理解することが重要です。

13
Lundin

すでに説明した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
Aconcagua

上記のように、このタイプの初期化は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 colir

注目すべきは、コンパイラが [〜#〜] 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   
2
ivaigult