- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个模板化类,里面有一个模板化函数(不同的模板参数),我在让编译器调用正确的函数时遇到问题。
例子:
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”这一事实有关
任何帮助都会很棒。谢谢。
最佳答案
是的,显式特化一个函数而不完全特化所有外部模板是不可能的(显式函数特化是一个真正的函数——它周围不能有任何“可变部分”仍然被模板参数化)
一种简单的方法是将 type2type 模板与重载一起使用:
template<typename T> struct t2t { typedef T type; };
void Func( Parm1 arg1, Parm2, arg2 ) { Call<Parm3>(arg1, arg2, t2t<Parm3>()); }
template< class Type, class V > void Call( Parm1 arg1, Parm2 arg2, t2t<V>) { }
template< class Type > void Call( Parm1 arg1, Parm2 arg2, t2t<void>) { }
现在,它将调用第二个 Call
如果用 t2t<void>
调用它会重载,否则第一个,因为第一个不那么特别。
使用 enable_if
也是可能的:
void Func( Parm1 arg1, Parm2, arg2 ) { Call<Parm3>(arg1, arg2); }
template< class Type > typename disable_if< is_same<Type, void> >::type
Call( Parm1 arg1, Parm2 arg2) { }
template< class Type > typename enable_if< is_same<Type, void> >::type
Call( Parm1 arg1, Parm2 arg2) { }
现在,如果Type
,则取第二个无效,如果 Type
则取第一个又是别的东西。但是使用不同的技术。这个叫做SFINAE
.另一种方法,但再次添加一个参数是这样的 - 以演示 SFINAE 的工作方式:
void Func( Parm1 arg1, Parm2, arg2 ) { Call<Parm3>(arg1, arg2); }
template< class Type >
void Call( Parm1 arg1, Parm2 arg2, char(*)[!is_same<Type, void>::value] = 0) { }
template< class Type >
void Call( Parm1 arg1, Parm2 arg2, char(*)[ is_same<Type, void>::value] = 0) { }
SFINAE
如果模板参数的替换产生无效类型或构造,则会发生这种情况。下面,我们尝试分别创建一个指向大小为 0 或 1 的数组的指针。大小为 0 的数组无效,并且会导致 SFINAE 失败 - 如果相应的模板特化是函数,则不会将其视为调用候选。
在enable_if
上述情况,它的工作方式不同。如果enable_if
给出了从 false_type
派生的东西, 然后它使它成为 ::type
typedef 不存在。 is_same
派生自 false_type
在这种情况下,类型不一样。然后我们会尝试访问一个不存在的名称——这是一个无效的构造,因此也会导致 SFINAE 失败。
关于c++ - 模板化类内部函数的模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/734797/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!