2016-11-18 23 views
0

私はテンプレートがCで定義されていないことを知っています。しかし、私の場合、C言語で記述されたAPIをC言語で書かれたアプリケーションで使用しています。 API内の関数です。Cのファイルからテンプレート関数を呼び出す

template<typename T> T function_name(T param1){ 
    ... 
    ... 
    return val; 
} 

abc.hppで宣言は以下の通り:

template<typename T> T function_name(T); 

この関数は以下のようにxyz.cから呼び出される:

int a ,b = 5; 
a = function_name(b); 
abc.cppに次のように関数が定義されています

ただし、abc.cppとabc.hppの両方に次のエラーが表示されます。

error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token 
template<typename T> 

extern "C"を使用しても助けになりません(エラー:Cリンケージを含むテンプレートにつながります)。私の疑問は、このような方法でこのテンプレート関数を呼び出すことさえ可能ですか?はいの場合、どのように達成できますか?ありがとうございました。

+3

「エラー:テンプレートにCリンケージがありません」というエラーが表示されます。それはC言語でC++を直接呼び出して行うことはできません。あなたは、テンプレート関数のインスタンス化のためにmangled C++名を知っていなければならず、次にCコードがそれを呼び出すでしょう。これは特定のC++コンパイラ(コンパイラの特定のバージョンでさえも)につながります。これを行う正しい方法は、 'extern" C "int template_int_function_name(int param1){return function_name(param1);}です。 } 'そして' Cは 'template_int_function_name()'を呼び出します。これにより、テンプレート関数用のC呼び出し可能ラッパーが提供されます。 –

+0

アプリケーションが突然C++(+)コンパイラでコンパイルする場合は、C++(+)で書かれることがあります。特に、malloc()の戻り値をキャストしないようにコードがアンワインドのアドバイスに従う場合、マイナーな適合が必要な可能性がありますが、編集は通常かなり軽微です。 –

+0

@JonathanLeffler Re:「文字化けした名前で直接テンプレート関数を呼び出す」:ライブラリ内にC++コードがない場合、インスタンス化は存在しないかもしれません(また、リンク時エラーにつながるかもしれません)。 。関数が、ライブラリに最近追加された可能性が高い場合。 –

答えて

1

既にCとC++を混在させているため(問題が発生している可能性があるため)、別の解決方法はアプリケーションをC++で開発し続けることです。そうすれば、新しいコードはテンプレートのようなC++ライブラリのすてきな機能を使用することができます;-)、オーバーロードされた関数など、C++の標準ライブラリにアクセスして生産性を大幅に向上させることができます。

アプリケーションで新しいソースファイルにC++を使用することに主な障害はありません。編集時に既存のCファイルをC++に切り替えることは容易に可能であり、価値があるかどうかは別の質問です。

8

もちろん、テンプレート関数はC言語には存在しません。テンプレート宣言をCコンパイラで解析することはできません。

テンプレートのintインスタンスのC++側にCラッパーを追加し、それを呼び出す必要があります(例:function_int()など)。

0

Cはテンプレートをサポートしていないので、ジェネリック式を定義するマクロベースのメソッドであるタイプジェネリック関数の使用を検討できます。

これが当てはまらない場合は、C++コンパイラを使用することをお勧めします。

+0

'_Generic'を意味するならば、それはマクロベースの解決策ではなく、言語の完全な演算子です - セクション§6.5.1.1の**標準で説明されています**セクションの一部である一般的な選択** 6.5.1 **主要な表現**。 6.10節ではプリプロセッサについて説明します。 –

関連する問題