以下代码可以与GCC(4.8及以上(一起编译,而MSVC(Visual Studio 2017,_MSC_VER 1910(给出了错误C2244:'a :: func':无法匹配现有声明的功能定义。
#include <iostream>
template<typename T, bool isInt= std::is_integral<T>::value >
class B
{
public:
using RET = T;
};
template <typename T>
class B <T, false>
{
public:
using RET = void;
};
template<typename T>
class A
{
using type = T;
public:
typename B<type>::RET func();
};
template<typename T>
typename B<typename A<T>::type>::RET A<T>::func()
{
std::cout << "func" << std::endl;
return 0;
}
int main()
{
A<int> a;
a.func();
return 0;
}
来自MSVC的完整错误消息:
error C2244: 'A<T>::func': unable to match function definition to an existing declaration
note: see declaration of 'A<T>::func'
note: definition
note: 'B<A<T>::type,std::is_integral<T>::value>::RET A<T>::func(void)'
with
[
T=A<T>::type
]
note: existing declarations
note: 'B<T,std::is_integral<_Ty>::value>::RET A<T>::func(void)'
如果我在B类中取消了模板专业化,则可以编译。
template<typename T>
class B
{
public:
using RET = T;
};
如果我不使用A类中的类型别名,也可以编译。
template<typename T>
class A
{
public:
typename B<T>::RET func();
};
template<typename T>
typename B<T>::RET A<T>::func()
{
std::cout << "func" << std::endl;
return 0;
}
,如果A类不是模板,它也可以编译。
class A
{
using type = int;
public:
typename B<type>::RET func();
};
在分离类成员声明和定义时,MSVC似乎不能很好地支持模板类,键入别名和模板专业化的混合使用。我不确定此用法是否有特殊术语。MSVC会在较新版本中支持这一点吗?或任何现有的编译选项可以修复?
已将此问题报告给Visual Studio开发人员社区。https://develovelercommunity.visualstudio.com/content/problem/225941/error-c2244-unable-to-match-function-definition-definition-to.html
今天遇到了同样的问题。我想这是MVSC中的错误。在15.9中仍然存在。