在类内定义友元函数模板时如何避免重定义错误?
考虑这段代码:
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
它现在编译得很好(ideone)。但是,如果我取消注释 B
的定义,则会出现以下错误 (ideone ):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined here
我知道(好吧,我想我知道)它给出这个错误的原因。
所以我的问题是:
在友元函数模板的类内定义的情况下如何避免重新定义错误?
只要我在类中提供主模板(不是专门化)的定义,我就会收到此错误。以这种方式定义主模板还有另一个问题:它使 f
函数模板的所有实例化为 Base
类模板的所有实例化的 friend
,我也想避免。我想让 f
成为 Base
的好友,但不让 f
成为 Base
的好友。如果
。同时我也想提供类内部的定义。是否可以?U
和 T
不相同,则 T>
Consider this code:
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
It compiles fine now (ideone). But if I uncomment the definition of B
, then it gives the following error (ideone):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined here
I know (well,I think I know) the reason why it gives this error.
So my question is :
How to avoid redefinition error in case of in-class definition of friend function template?
As long as I provide the definition of the primary template (not specialization) inside the class, I will get this error. There is also another problem with defining primary template in this way: it makes all instantiations of f
function template friend
of all instantiations of Base
class template, which I also would like to avoid. I want to make f<T>
a friend of Base<T>
but not f<U>
a friend of Base<T>
if U
and T
are not same. At the same time, I also want to provide the definition inside the class. Is it possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您真的需要在类中定义
f
吗?如果您在外部定义它,您的问题就会消失,并且您还可以强制执行您想要的一对一关系(即只有f
是Base
的友元。 code>):但是,请注意,只有
f
是Base
的友元这一事实不会阻止以下代码的编译:Do you really need to define
f
into the class? If you define it outside, your problem disappears and you can also enforce the one-to-one relationship you want (i.e. onlyf<T>
is a friend ofBase<T>
):However, note that the fact that only
f<T>
is a friend ofBase<T>
will not prevent the following code from compiling:友元函数是一个全局函数,即使您将其实现放入任何类的主体中也是如此。问题是,当您实例化
Base
两次(在任何上下文中)时,您提供了f
的两个实现。请注意,f
不依赖于T
,并且它不能使用T
;对于所有Base
来说,它的功能都是相同的。一个简单的解决方案是仅在类模板内提供
f
的声明并在其外部提供实现:上面的代码使用我的 g++ 进行编译
A friend function is a global function, even if you put its implementation into the body of any class. The problem is that when you instantiate
Base<T>
twice (in any context) you provide two implementations off
. Note, thatf
does not depend onT
, and it cannot useT
; it's the same function for allBase<T>
.A simple solution is to provide only the declaration of
f
within the class template and implementation outside it:The above code compiles with my g++