提问者:小点点

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


如果我在一个头文件的命名空间中定义了一个默认函数'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);
    }
}

除非确保fooOverloads.h在bar.h的。include之前是。includeded,或者确保fooOverloads.h在bar.h中是。includeded,或者我为FooNamespace中的一个虚拟类提供了一个'foo'函数的声明,并在bar.h中提供了。include,否则'bar'将无法编译,例如。

//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个答案

匿名用户

我的解决方案是去掉无用的命名空间。将默认的放在与重载相同的命名空间中,则只需:

using FooNamespace::foo;
foo(x);

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

我认为没有理由将默认的放在一个单独的名称空间中,特别是因为这样做需要一个单独的虚拟定义来使成为有效代码,而相同的重载可以同时用于两个目的。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(命名|空|间中|模板|函数|调用|c++|命名|空间|限定|函数)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?