错误 C2244 在具有模板化参数函数的模板化成员变量上,仅在 Visual Studio 上发生

error C2244 on templated member variable with templated argument function, only happens on Visual Studio

本文关键字:仅在 变量 Studio Visual 函数 C2244 参数 错误 成员      更新时间:2023-10-16

我在Visual Studio上遇到了一个有趣但非常烦人的错误,下面是最简单的重现:(取消注释 #define 将允许VS构建代码)

#include <iostream>
using namespace std;
//#define BUILD_ON_VS
class CC
{
public:
   template<typename T>
   struct Foo
   {
      template<T foo>
      void bar()
      {
         cout << "VC likes this!n";
      }
#ifndef BUILD_ON_VS
      template<T foo>
      void bar1();
#endif
   };
   Foo<int> m_foo;
};
#ifndef BUILD_ON_VS
template<typename T>
template<T foo>
void CC::Foo<T>::bar1()
{
   cout << "VC doesn't like this...n";
}
#endif
int main()
{
   CC cc;
   cc.m_foo.bar<-1>();
#ifndef BUILD_ON_VS
   cc.m_foo.bar1<2>();
#endif
   return 0;
}

基本上,我不能将函数栏的定义放在Visual Studio中的类之外。 否则,bar 和 bar1 完全相同。在 VS 2010 和 VS 2012 上进行测试,均失败并显示错误:

error C2244: 'CC::Foo<T>::bar1' : unable to match function definition to an existing declaration
definition
'void CC::Foo<T>::bar1(void)'
existing declarations
'void CC::Foo<T>::bar1(void

但是,它适用于所有在线编译器,例如 compileonline 和 ideone。

我想将所有内容保存在 cpp 文件中,而不是在 .h 中以保持代码库干净。

Setting var1 to:
{
   template<typename TT, TT foo>
   void bar1();
}
template<typename T>
template<typename TT, TT foo>
void CC::Foo<T>::bar1()
{
}

也可以,但它通过重新定义相同的模板参数使代码看起来很愚蠢,并且更容易出现错误。这也使界面变得混乱。

通过随机输入找到修复程序,看看它是否可以编译,哈哈!!看起来有点愚蠢......

#include <iostream>
using namespace std;
//#define BUILD_ON_VS
class CC
{
public:
   template<typename T>
   struct Foo;
   Foo<int>* m_foo;
   template<typename T>
   struct Foo
   {
      template<T foo>
      void bar();
   };
};
template<typename T>
template<T foo>
void CC::Foo<T>::bar()
{
   cout << "VC happen to like this...n";
}
int main()
{
   CC cc;
   cc.m_foo = new CC::Foo<int>;
   cc.m_foo->bar<2>();
}

我需要创建一个抽象类并使用模板参数实例化它;

想知道为什么VC不能像GCC那样自动做到这一点。