在某些名称空间中定义方法时,在全局名称空间中声明?

时间:2019-02-17 17:00:04

标签: c++ visual-studio templates namespaces

我的代码包含两部分-名称空间test中的类模板my和全局名称空间中的函数frobnicate。类模板希望在其方法之一中使用此函数,而我想在其使用附近声明它:

namespace my
{
    template <class T>
    struct test
    {
        void do_stuff(T& i)
        {
            void frobnicate(T&);
            frobnicate(i);

            // more code here
        }
    };
}

struct SomeClass {};

void frobnicate(SomeClass& i)
{
    // some code here
}

int main()
{
    my::test<SomeClass> t;
    SomeClass object;
    t.do_stuff(object);
}

由于存在错误(在here中描述),此方法在MS Visual Studio 2017中有效,因为Visual Studio在全局名称空间中声明了该函数,而根据标准,此类声明在当前名称空间中声明了该函数。 / p>

但是,海湾合作委员会理所当然地抱怨:

  

...对`my :: frobnicate(SomeClass&)'的未定义引用

我可以使其在gcc或任何其他符合标准的编译器中工作吗?


如果将frobnicate的声明放在声明模板test的前面,则代码有效。但是,在我的实际代码中,这两个代码部分位于不相关的头文件中,并且我希望我的代码能够工作,而不考虑#include的顺序。

2 个答案:

答案 0 :(得分:1)

只需在命名空间之前将您的frobnicate函数声明为模板即可。

template <class T>
void frobnicate(T&);

namespace my {

template <class T>
struct test
{
    void do_stuff(T& i)
    {
        frobnicate(i);
        // more code here
    }
};
}  // close my namespace

答案 1 :(得分:0)

我认为您可以简单地在单独的文件中声明frobnicate并在创建名称空间my之前将其包括在内。也可以在同一文件中将函数声明为带有#define的宏。然后,您可以在frobnicate的{​​{1}}中呼叫do_stuff

否则,您将无法调用未定义的函数。