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

Calling a C++ namespace-qualified function within a template function in another namespace

本文关键字:函数 空间 c++ 调用 另一个      更新时间:2023-10-16

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

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

和在另一个命名空间中定义的foo的重载在一个或多个其他头文件中,例如,foo重载.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'不会编译,除非我要么确保foo重载。h是#include在bar .h的#include之前,或者我确保foo重载。h是#include在bar .h,或者我提供一个'foo'函数的声明为一个虚拟类在FooNamespace和#include在bar .h,例如

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

是否有任何方法,这样我可以定义酒吧,避免创建冗余的代码来打开酒吧的FooNamespace ?

我的解决方案是去掉无用的DefaultFooNamespace名称空间。将默认的foo放在与重载相同的名称空间中,然后bar只做:

using FooNamespace::foo;
foo(x);

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

我看不出默认的foo在一个单独的名称空间中有什么理由,特别是因为这样做需要一个单独的虚拟定义来使bar有效的代码,当相同的重载可以同时满足两个目的时。