26

専門家向けの簡単な説明: C++11 では、名前のない名前空間を宣言できますinline。これは冗長に思えます。名前のない名前空間で宣言されたものは、囲んでいる名前空間で宣言されているかのように既に使用されています。

だから私の質問はこれです:言うことはどういう意味ですか

inline namespace /*anonymous*/ {
    // stuff
}

そして、それは伝統的なものとどう違うのですか

namespace /*anonymous*/ {
    // stuff
}

私たちが C++98 から知っていて、愛しているのは? を使用した場合の異なる動作の例を誰か挙げてもらえますinlineか?

編集:この質問は重複としてマークされているため、明確にするために:名前付きインライン名前空間全般について質問しているわけではありませ。私はそこでのユースケースを理解しており、素晴らしいと思います。名前のない名前空間を として宣言することの意味を具体的に尋ねていますinlineinline名前のない名前空間は常にTUに対してローカルであるため、シンボルのバージョン管理の合理性は適用されないようです。


余談ですが、名前のない名前空間に関する標準 [7.3.1.1] は次のように述べています。

inlineunnamed-namespace-definitionに表示される場合にのみ表示されます

しかし、これは言語を知らない私の弁護士の目にはトートロジーのように見えます。おまけとして、このちょっとした標準語が実際に何を言っているのか説明できる人はいますか?

編集: Cubbiはコメントでボーナスポイントを主張しました:

標準では、unnamed-namespace-definition は、unnamed-namespace-definitionに表示される場合、 Xに表示されるXに置き換えられたかのように動作すると述べています。inline

4

2 に答える 2

15

SOに関するあなた自身の質問に答えるのが終わったことかどうかはわかりませんが、いくつか遊んだ後、私の好奇心が満たされたので、それを共有することもできます.

インライン名前空間の定義には、囲んでいる名前空間への名前の巻き上げ (名前のない名前空間の場合に発生します) だけでなく、インライン名前空間内で定義されたテンプレートをその外部で特殊化することもできます。これは、名前のない名前空間にも当てはまることがわかりました。

inline // comment this out to change behaviour
namespace { 
    template <typename T> struct A {};
}

template <> struct A<int> {};

がないとinline、g++ は別の名前空間からテンプレートを特殊化しようとすると文句を言います (ただし、Clang はそうではありません)。を使用inlineすると、問題なくコンパイルされます。両方のコンパイラで、特殊化内で定義されたものはすべて、あたかも名前のない名前空間内にあるかのように、内部リンケージを持つものとしてマークされます( に従って) が、これは予想されることだと思います。nmこれが役立つ理由はまったく思い浮かびませんが、これで終わりです。

おそらくより有用な効果は、名前のないインライン名前空間にも影響する、インライン名前空間の引数依存ルックアップに関する変更から得られます。次のケースを検討してください。

namespace NS {
    // Pretend this is defined in some header file
    template <typename T>
    void func(const T&) {}

    // Some type definition private to this TU
    inline namespace {
        struct A {};
    }

} // end namespace NS

int main()
{
    NS::A a;
    func(a);
}

がないinlineと、ADL が失敗し、明示的に記述する必要がありますNS::func(a)。もちろん、名前のない名前空間をトップレベルで定義した場合 (通常のように)、インラインであるかどうかにかかわらず ADL を取得できませんが、それでも...

于 2013-11-26T08:41:48.723 に答える