log
グローバル名前空間( )にクラスを持つプロジェクトがあります::log
。
したがって、当然のことながら、その後#include <cmath>
、ログクラスのオブジェクトをインスタンス化しようとするたびに、コンパイラはエラーメッセージを表示します。これ<cmath>
は、グローバル名前空間を多数の3文字のメソッド(そのうちの1つは対数関数)で汚染するためlog()
です。
したがって、3つの可能な解決策があり、それぞれに固有の醜い副作用があります。
- ログクラスをそれ自体の名前空間に移動し、常に完全修飾名でアクセスします。ロガーはできるだけ使いやすいはずなので、これは避けたいと思います。
mathwrapper.cpp
を含むプロジェクト内の唯一のファイルであるファイルを作成<cmath>
し、必要なすべての<cmath>
関数を。のラッパーを介して使用できるようにしnamespace math
ます。必要なすべての数学関数のラッパーを作成する必要があるため、このアプローチを使用したくありません。これにより、呼び出しペナルティが追加されます(-flto
コンパイラフラグによって部分的にキャンセルされます) 。- 私が現在検討している解決策:
交換
#include <cmath>
に
namespace math {
#include "math.h"
}
次に、を介して対数関数を計算しmath::log()
ます。
私はそれを試してみましたが、実際、期待どおりにコンパイル、リンク、実行されます。ただし、複数の欠点があります。
- コードは完全修飾名で関数にアクセスし、C ++での使用は非推奨で
<cmath>
あるため、(明らかに)使用することは不可能です。<cmath>
- 猛禽類に襲われて生きたまま食べられるような、本当に本当に悪い気持ちになります。
だから私の質問は:
- 名前空間にincludeディレクティブを入れることを禁止する推奨事項/規則などはありますか?
何かがうまくいかない可能性があります
- 異なるC標準ライブラリの実装(私はglibcを使用しています)、
- さまざまなコンパイラ(私はg ++ 4.7、-std = c ++ 11を使用)、
- リンク?
- これをやってみたことがありますか?
- グローバル名前空間から数学関数を削除する別の方法はありますか?
私はstackoverflowでいくつかの同様の質問を見つけましたが、ほとんどは他のC ++ヘッダーを含めることに関するものでしたが、これは明らかに悪い考えであり、Cライブラリのリンク動作について矛盾したステートメントが作成されていませんでした。#include <math.h>
また、中に追加で入れるといいのextern "C" {}
でしょうか?
編集
そこで、おそらく他のすべての人が行っていることを実行し、すべてのコードをプロジェクトの名前空間に配置し、を含めるときに完全修飾名でロガーにアクセスすることにしました<cmath>
。