类模板成员函数无法显式特化的原因与解决方式咨询
类模板成员函数显式特化报错问题
问题描述
我在类中声明了如下模板成员函数:
class A { template<typename T, typename... ARGS> void Func( ARGS&&... args) { //DoSomeWork } };
随后尝试针对int类型对其进行显式特化:
template<> void A::Func<int>(bool arg) { //DoSomeOtherWork }
但出现错误:
error C2910: 'A::Func': cannot be explicitly specialized
请问是否可以特化该模板?若无法特化,原因是什么?
解答
不能按照你写的方式特化,核心原因有两个:
模板参数必须完全指定
原函数模板包含两个模板参数:T和可变参数包ARGS。显式特化要求必须明确指定所有模板参数,不能只指定T=int而让ARGS留待推导。你当前的写法没有给出ARGS的具体类型,不符合特化的语法要求。特化签名必须与原模板严格匹配
就算你指定了所有模板参数,还要保证参数类型和原模板一致。原模板的参数是ARGS&&...(转发引用),如果ARGS指定为bool,参数类型应该是bool&&,但你写的特化参数是bool arg(左值),这会导致签名不匹配,就算解决了参数问题也会报错。
如果一定要做显式特化,正确的写法应该是这样(以ARGS为bool为例):
template<> void A::Func<int, bool>(bool&& arg) { //DoSomeOtherWork }
不过更推荐的方式是用重载替代特化,函数模板特化的规则复杂且容易踩坑,重载的写法更直观:
class A { template<typename T, typename... ARGS> void Func( ARGS&&... args) { //DoSomeWork } // 针对bool参数的重载 void Func(bool arg) { //DoSomeOtherWork } };
如果需要绑定T=int的逻辑,可以在原模板里用constexpr if做分支处理,或者用标签分发的方式,比特化更灵活。
内容的提问来源于stack exchange,提问作者TStancek
相关产品推荐
相关产品推荐

