0

1つのヘッダーファイルの名前空間にデフォルトの関数「foo」が定義されている場合:

//DefaultFoo.h
namespace DefaultFooNamespace
{
    template <typename T>
    void foo(T& x){/*...*/}
}

1つ以上の他のヘッダーファイルの別の名前空間で定義されたfooのオーバーロード(例:FooOverloads.h:)

//FooOverloads.h
namespace FooOverloadsNamespace
{
    template <typename T>
    void foo(std::vector<T>& x){/*...*/}

    void foo(std::string& x){/*...*/}

    //etc.
}

DefaultFooNamespaceとFooOverloadsNamespaceの両方の名前空間をスコープに入れた後にfooを呼び出す別の関数'bar'があります(DefaultFoo.hには名前空間に単一の関数が含まれているため、Bar.hにはDefaultFoo.hのみが含まれていることに注意してください追加のオーバーロードの追加によって拡張されるFooOverloadsNamespaceとは異なり、拡張されます):

//Bar.h
#include "DefaultFoo.h" 

namespace BarNamespace
{
    template <typename T>
    void bar(T& x)
    {
        //... do stuff then call foo
        using DefaultFooNamespace::foo;
        using FooOverloadsNamespace::foo;
        foo(x);
    }
}

FooOverloads.hがBar.hの#includeの前に#includeされていることを確認するか、FooOverloads.hがBar.hに#includeされていることを確認しない限り、「bar」はコンパイルされません。 FooNamespaceのダミークラスに「foo」関数の宣言を提供し、Bar.hに#includeします。例:

//Dummy.h:
struct DummyClass
{
private:
    DummyClass(){}
};
namespace FooNamespace
{
    inline void foo(DummyClass& x);  //purely to open up namespace
}

//Bar.h
#include "Dummy.h"

これを回避する方法はありますか?バーを定義して、バーでFooNamespaceを開くために冗長なコードを作成する必要をなくすことができますか?

4

1 に答える 1

0

DefaultFooNamespace私の解決策は、役に立たない名前空間を取り除くことです。デフォルトfooをオーバーロードと同じ名前空間に配置してから、次のbarようにします。

using FooNamespace::foo;
foo(x);

foo呼び出し元が次のタイプに対してより適切な定義を含めていない場合は、デフォルトが使用されます。x

fooデフォルトが別の名前空間にある理由はわかりません。特にbar、同じオーバーロードが両方の目的に役立つ可能性がある場合に、有効なコードを作成するために別のダミー定義が必要になるためです。

于 2013-01-20T16:53:14.410 に答える