MSVC 2019编译报错C2988:模板声明无法识别,该如何解决?
问题:MSVC 2019编译C++模板时触发C2988错误(Xcode编译正常)
我遇到了错误C2988(无法识别的模板声明/定义),光标提示位置紧邻method参数的*之前。代码如下:
namespace Bind { template <typename ModelClass, typename ReturnType> static std::unique_ptr<Binding> Get (ReturnType (ModelClass::*method)(), const String& source, const Symbol& aspect = {}) { // whatever return nullptr; } // .... }
示例实例化(WhateverClass::whateverMemberFunction()返回ReturnType且无参数,模板参数ModelClass和ReturnType本应通过实例化推导得出):
Bind::Get(&WhateverClass::whateverMemberFunction, "")
该模板在Xcode(Apple Clang编译器)中使用C++17标准编译正常,但在MSVC 2019中编译失败。请问问题出在哪里?
原因与解决方案
MSVC的模板语法解析器对复杂类型的换行和写法更为严格,此处报错是因为编译器无法正确解析模板函数参数中的成员函数指针类型,加上static修饰符和换行的组合进一步加剧了解析歧义。
解决方案1:用using封装成员函数指针类型
通过类型别名简化成员函数指针的写法,消除解析歧义:
namespace Bind { // 定义成员函数指针的类型别名 template <typename ModelClass, typename ReturnType> using MemberFunction = ReturnType (ModelClass::*)(); template <typename ModelClass, typename ReturnType> static std::unique_ptr<Binding> Get(MemberFunction<ModelClass, ReturnType> method, const String& source, const Symbol& aspect = {}) { // whatever return nullptr; } // .... }
解决方案2:调整函数声明的换行格式
将返回类型与函数名放在同一行,避免换行导致的解析混乱:
namespace Bind { template <typename ModelClass, typename ReturnType> static std::unique_ptr<Binding> Get(ReturnType (ModelClass::*method)(), const String& source, const Symbol& aspect = {}) { // whatever return nullptr; } // .... }
两种方案都能让MSVC正确解析模板声明,同时保持代码的可移植性,在Clang下也能正常编译。
内容的提问来源于stack exchange,提问作者Anders
相关产品推荐
相关产品推荐

