0

如果我在一个头文件的命名空间中定义了默认函数“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 中仅 #include 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'd,或者我确保 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?

4

1 回答 1

0

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

using FooNamespace::foo;
foo(x);

foo如果调用者没有包含更合适的类型的定义,则使用默认值x

我看不出默认值foo位于单独的命名空间中的原因,特别是因为这样做需要单独的虚拟定义来生成bar有效代码,而相同的重载可以同时满足这两个目的。

于 2013-01-20T16:53:14.410 回答