在另一个名称空间中的模板函数内调用C ++名称空间限定的函数

时间:2013-01-20 14:32:02

标签: c++ namespaces

如果我在一个头文件中的命名空间中定义了默认函数'foo':

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

和一个或多个其他头文件中另一个命名空间中定义的foo重载,例如FooOverloads.h:

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

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

    //etc.
}

我有另一个函数'bar'在将DefaultFooNamespace和FooOverloadsNamespace命名空间放入范围后调用foo(注意我在Bar.h中只包含DefaultFoo.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);
    }
}

'bar'将无法编译,除非我确保FooOverloads.h在Bar.h的#include之前是#include,或者我确保FooOverloads.h在Bar.h中是#include'd,或者我在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"

有没有办法解决这个问题,这样我就可以定义bar并避免在Bar中创建冗余代码来打开FooNamespace?

1 个答案:

答案 0 :(得分:0)

我的解决方案是摆脱无用的DefaultFooNamespace命名空间。将默认的foo放在与重载相同的命名空间中,然后bar就是:

using FooNamespace::foo;
foo(x);

如果调用方没有为foo

类型包含更合适的定义,则使用默认x

我没有看到默认foo在一个单独的命名空间中的原因,特别是因为这样做需要一个单独的虚拟定义来生成bar有效代码,当相同的重载可以服务时两个目的。