我的代码包含两部分-名称空间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
的顺序。
答案 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
。
否则,您将无法调用未定义的函数。