2016-05-23 21 views
9

ヘッダーは、関数metaを定義し、C++メタプログラミングライブラリmetaは、すべてのコードをグローバル名前空間metaに置きます。C++ライブラリ名前空間とC linux関数との間の名前の衝突

同じC++プログラムで両方を使用するにはどうすればよいですか(必ずしも同じTUでなくてもかまいません)。名前の衝突を回避する方法はありますか?

を私は2つの脆性の回避策を考えることができますが、彼らは壊れやすいです:

  • 回避策A:

    namespace linux { 
    #include <ncurses.h> 
    } // namespace linux 
    using linux::max_align_t; // ncurses assumes it is in the global namespace 
    #include <meta/meta.hpp> 
    

    コンパイルおそらくncursesシンボルがに期待されているため、リンクに失敗しますグローバル名前空間。

  • 回避策B:それは唯一の限りmetaライブラリがそのシンボルのいずれかがグローバル名前空間にあることを想定していないように動作しますので、

    #include <ncurses.h> 
    namespace cpp { 
    #include <meta/meta.hpp> 
    } // namespace cpp 
    

    は非常に脆いです。つまり、ライブラリが内部的にシンボルを明確にする必要があり、そのために::meta::symbol_nameを使用すると、このアプローチは中断されます。

+1

アプローチAは、あなた自身が知っているとおりに動作しません。アプローチBが動作するかもしれません - 試してみてください。しかし、私は最初に、私がこれらの2つの図書館を分けることができるかどうかを確かめることができます。 – SergeyA

+3

同じ翻訳単位に両方のヘッダーを含めることはないように、ラッパーを作成してみてください。そうすれば、リンカーでうまくいけばいいと思います。 – nwp

+0

@NathanOliver ''にはmetaという関数がありますが、 ''はグローバル名前空間内で 'meta'という名前空間を持っているので、関数名は名前空間の名前と衝突します。 – gnzlbg

答えて

7

私は、回避策のCをお勧めします:meta図書館利用とncurses使用は、プロジェクト内の別々の翻訳単位にあるように、あなたのコードを分離します。このように、特定の翻訳単位では、名前空間とグローバル関数の両方として1つのシンボルが使用されることはありません。

+0

メタはヘッダのみのライブラリなので、おそらくこのヘッダをそのcppファイルに含む ''の周りにラッパを書く方が簡単でしょう。 – gnzlbg

+0

@gnzlbg少し見てみると、すでに使用できるncursesライブラリ用のC++ラッパーがあることは確かです。 :) –

+2

@JoachimPileborg不要:ncursesにはすでにC++バインディングが含まれています(http://stackoverflow.com/questions/544280/c-wrappers-for-ncurses) – Garf365

1

私は、AとBのどちらも実際には、少なくとも与えられた通りには動作しないと確信しています。あなたはそれらの1つを指してきましたが、私はそれが2つの可能性が低いと思います。基本的に互いに鏡像関係にある2つの問題があります。

ncursesでコードが名前空間にそれらを囲む、extern "C"(C++で動作するように作られてきた多くのCライブラリの標準)として宣言されている場合は、実際には動作しません - extern "C"宣言は、基本的に名前空間を無視し、宣言するグローバルな名前空間の関数名前空間は何も変更されず、あなたはまだ衝突します。

<ncurses.h>の内容はextern "C"宣言されていない場合は、あなたが引用した問題に遭遇します:ライブラリは、グローバル名前空間内の関数を使用して構築されますが、クライアントコードはlinux名前空間内のコードの定義を見ています。名前空間は、名前が変更された場合に影響を受けます(つまり、衝突を防ぐ方法です)ので、コードをリンクすることはできません。 linux::*の機能はすべて未解決の外部として表示されます。

は、この作業を行うには、あなたはライブラリコードのいずれもextern "C"を宣言されていないことを保証し、名前空間内部ヘッダ(およびライブラリのソースファイル)を指定し、これらの宣言でライブラリを再コンパイルする必要があり、ライブラリとそのクライアントコードは、そのコードが存在する名前空間で同意します。