Iは、次のヘッダーを持っている:私は、コンパイルされたとき名前空間内の関数の宣言と定義?
#ifndef MY_H_
#define MY_H_
namespace A {
void f() {
// do something
}
}
#endif
しかし、私は):: Fを(複数の定義のようなエラーを得ました。私は#ifndefチェックが1翻訳単位で重複する定義を避けるのに十分だと考えました。多分私は何かが恋しいですか?
ありがとうございます。
Iは、次のヘッダーを持っている:私は、コンパイルされたとき名前空間内の関数の宣言と定義?
#ifndef MY_H_
#define MY_H_
namespace A {
void f() {
// do something
}
}
#endif
しかし、私は):: Fを(複数の定義のようなエラーを得ました。私は#ifndefチェックが1翻訳単位で重複する定義を避けるのに十分だと考えました。多分私は何かが恋しいですか?
ありがとうございます。
は、関数定義の前にinline
指定子を追加します。
#ifndef MY_H_
#define MY_H_
namespace A {
inline void f() {
// do something
}
}
#endif
私のコンパイラではInlineが動作します。しかし、インラインはコンパイラのヒントにすぎないので、コンパイラはそれを無視して、複数の定義で終わります。または、コンパイラはこの場合インラインを無視しないことが保証されていますか? – Hei
上のリンクの説明の第1のポイントに従う: "1)インライン関数の定義は、異なる変換単位に現れる限り、プログラム内に複数の定義が存在する可能性があります。複数のソースファイルに#includeされているヘッダファイル内にあります。 "コンパイラの最適化ヒントとしてのインラインは廃止されました。 – pmed
お返事ありがとうございます。つまり、新しいC++標準(C++ 11またはC++ 14)では、コンパイラはインラインでヒントを取るのではなく、インラインで正しく処理する必要がありますか? – Hei
ヘッダーファイルに関数を宣言して、関数をcppファイルで定義する必要があります。このヘッダーファイルを複数の翻訳単位(可能性が最も高い)から含めると、異なる翻訳単位で複数の実装が利用可能になります。このヘッダーを含む各cppファイルの実装はf
になります。このようにして、f
を呼び出す場合は、あいまいです。実装をcppファイルに入れることで、その方法でリンクして使用することができます。しかし、それを明確にする実装は1つしかありません。
だから、あなたのヘッダファイルは次のようになります。
#ifndef MY_H_
#define MY_H_
namespace A
{
void f(); // declaration only
}
#endif
とソースファイル:
#include "myHeader.h"
namespace A
{
void f()
{
// some implementation
}
}
その後、あなたは問題ないはずです。あなたは通常、あなたのすべての機能でそれを行います。唯一の例外はinline
関数/メソッドまたはテンプレートですが、これはこの質問の範囲を超えています。
を使用すると、複数の定義の問題は、*複数の*翻訳単位にappertainという事実を逃している、いない1つの翻訳単位に。 –
@KerrekSBあなたの迅速な対応に感謝します。はい、私はあなたが意味するものを参照してください。私は問題を避けるために静的にすることができます。インラインも私のコンパイラで動作します。しかし、インラインはコンパイラのヒントにすぎないので、コンパイラはそれを無視して、複数の定義で終わります。または、コンパイラはこの場合インラインを無視しないことが保証されていますか? – Hei
本当の答えはヘッダーに定義を入れることではありません。次に、複数の定義を取得しないでください! –