模板类内部函数的模板特化
我有一个模板化类,里面有一个模板化函数(不同的模板参数),并且我在让编译器调用正确的函数时遇到问题。
示例:
template< class Parm1, class Parm2, class Parm3 >
class Class {
public:
void Func( Parm1 arg1, Parm2 arg2 ) {
Call<Parm3>( arg1, arg2 );
}
protected:
template< class Type >
void Call( Parm1 arg1, Parm2 arg2 ) {
}
template<>
void Call<void>( Parm1 arg1, Parm2 arg2 ) {
}
};
因此,如果 Parm3 的类型为“void”,我希望调用第二个 Call。 否则第一。 VS 工作正常,但 GCC 却很恶心。 它总是调用第一个。 现在这是一个非专业类专业化的问题,还是与我专业化“void”这一事实有关?
任何帮助都会很棒。 谢谢。
I have a templated class and inside I have a templated function( different template parameters ) and I having issues getting the compiler to call the correct one.
Example:
template< class Parm1, class Parm2, class Parm3 >
class Class {
public:
void Func( Parm1 arg1, Parm2 arg2 ) {
Call<Parm3>( arg1, arg2 );
}
protected:
template< class Type >
void Call( Parm1 arg1, Parm2 arg2 ) {
}
template<>
void Call<void>( Parm1 arg1, Parm2 arg2 ) {
}
};
So if the type of Parm3 is 'void' I want the second Call to be called. Otherwise the first. VS it works fine but GCC pukes all over it. It always calls the first one. Now is this an issue with specializing within of an unspecialized class or does it have something to do with the fact that Im specializing with 'void'
Any help would be great. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,在不完全专门化所有外部模板的情况下显式专门化函数是不可能的(显式函数专门化是一个真正的函数 - 它周围不能有任何仍由模板参数化的“可变部分”)
一种简单的方法是将 type2type 模板与重载结合使用:
现在,如果您使用
t2t
调用它,它将调用第二个Call
重载,否则将调用第一个重载,因为第一个重载不太特别。使用
enable_if
是可能的太:现在,如果
Type
为空,则采用第二个,如果Type
再次为其他值,则采用第一个。 但使用不同的技术。 这个称为SFINAE
。 另一种方法,但再次添加一个参数是这样的 - 演示 SFINAE 的工作方式:如果模板参数的替换产生无效类型或构造,则会发生
SFINAE
。 下面,我们尝试创建一个分别指向大小为 0 或 1 的数组的指针。 大小为 0 的数组无效,并且会导致 SFINAE 失败 - 如果相应的模板特化是函数,则不会将其视为调用候选者。在上面的
enable_if
情况下,它的工作方式有所不同。 如果enable_if
被赋予从false_type
派生的东西,那么它会使其::type
typedef 不存在。is_same
在类型不同的情况下派生自false_type
。 然后我们会尝试访问一个不存在的名称 - 这是一个无效的构造,因此也会导致 SFINAE 失败。Yes, explicitly specializing a function without fully specializing all outer template is not possible (an explicit function specialization is a real function - there can't be any "variable parts" around it that are still parameterized by a template)
A simple way is to use a type2type template together with overloading:
Now, it will call the second
Call
overload if you call it witht2t<void>
, and the first otherwise, because the first one is less special.Using
enable_if
is possible too:Now, the second one is taken if
Type
is void, and the first one is taken ifType
is something else again. But using a different technique. This one is calledSFINAE
. An alternative way, but which again adds one parameter is this - to demonstrate the way SFINAE works:SFINAE
happens if the substitution of a template parameter yields to an invalid type or construct. Below, we try to create a pointer to an array of size 0 or 1 respectively. An array of size 0 is not valid, and will cause an SFINAE failure - the corresponding template specialization will not be considered as a call-candidate if it is a function.In the
enable_if
case above, it works different. Ifenable_if
is given something derived fromfalse_type
, then it makes its::type
typedef not existent.is_same
derives itself fromfalse_type
in the case types are not the same. We would then try to access a not existent name - which is an invalid construct and would therefor be an SFINAE failure too.