如果我在一个头文件中的命名空间中定义了默认函数'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?
答案 0 :(得分:0)
我的解决方案是摆脱无用的DefaultFooNamespace
命名空间。将默认的foo
放在与重载相同的命名空间中,然后bar
就是:
using FooNamespace::foo;
foo(x);
如果调用方没有为foo
x
我没有看到默认foo
在一个单独的命名空间中的原因,特别是因为这样做需要一个单独的虚拟定义来生成bar
有效代码,当相同的重载可以服务时两个目的。