以下代码是重现失败的程序和类的基本部分:
using namespace System;
generic <class T>
ref class gener
{
public:
void func1g (T value)
{
Console::WriteLine (value);
int iValue = static_cast<int>(value);
if (iValue <= 0) return;
func2 ();
}
void func2 ()
{
T value = (T)(Object^)0;
func1g (value);
}
};
int main()
{
gener<int>^ g = gcnew gener<int>;
int iValue = 1;
g->func1g (iValue); // <<=== System.TypeLoadException
return 0;
}
致电func1g
时,我会收到System.TypeLoadException
。我只是不明白为什么
是因为func2
没有通用参数吗?
这里有完整的错误消息(德语,但它只是说&#39;未处理的例外情况&#39;并且&#39;无法加载&#39 ;;没有详细信息):
C#中的等效代码有效:
public class gener<T>
{
public void func1g(T value)
{
Console.WriteLine(value);
int iValue = Convert.ToInt32(value);
if (iValue <= 0) return;
func2();
}
public void func2()
{
T value = (T)(object)0;
func1g(value);
}
};
internal class Program
{
private static void Main()
{
gener<int> g = new gener<int>();
int iValue = 1;
g.func1g(iValue);
return;
}
}
我找到了一种解决方法&#39;,请参阅下面的答案,但我不知道为什么会这样做。
如果有人能解释这次失败的原因以及解决方法的功能,我将不胜感激。
编辑2
如果你想重现这个:我使用VS 2008 SP1
我希望它不再像我上一期那样编译器相关,尽管我个人认为这很可能......
答案 0 :(得分:2)
经过一些测试,我刚刚找到了解决这个特定问题的方法:
我需要按如下方式定义func1g
:
generic <class T>
void func1g (T value)
{
...
}
但我不明白为什么 两种方式(问题中的代码和此解决方案)编译良好,但第一种方式产生运行时异常,请参阅帖子。
还有一个问题:
请注意,上面的func1g
是在同一位置声明和定义的!
我的原始代码分为.h和.cpp,如下所示:
generic <class T>
ref class gener
{
public:
generic <class T>
void func1g (T value);
void func2 ()
{
T value = (T)(Object^)0;
func1g (value);
}
};
generic <class T>
void gener<T>::func1g (T value)
{
Console::WriteLine (value);
int iValue = static_cast<int>(value);
if (iValue <= 0) return;
func2 ();
}
现在编译器抱怨error C2511: 'void gener<T>::func1g(T)': overloaded member function not found in 'gener<T>'
因此我继续玩游戏(它确实是试验和错误)并找到了一个可行的解决方案,我完全不理解:
using namespace System;
generic <class T>
ref class gener
{
public:
generic <class T2>
void func1g (T2 value);
void func2 ()
{
T value = (T)(Object^)0;
func1g (value);
}
};
generic <class T>
generic <class T2>
void gener<T>::func1g (T2 value)
{
Console::WriteLine (value);
int iValue = static_cast<int>(value);
if (iValue <= 0) return;
func2 ();
}
int main()
{
gener<int>^ g = gcnew gener<int>;
int iValue = 1;
g->func1g (iValue);
return 0;
}
有人可以向我解释一下吗?
我实际上并不知道双generic
定义是可能的。
答案 1 :(得分:-1)
这是C#代码(顺便说一下,除非T
是System.Int32
或System.Int32
,否则它在C#中也被破坏了,你应该使用default(T)
),这在C ++ /中是不合理的CLI。
void func2 ()
{
T value = (T)(object)0;
func1g(value);
}
仅仅因为C ++ / CLI编译器接受完全相同的代码,并不意味着它做同样的事情!
object
是C#中的关键字,我不知道您为C ++ / CLI添加了哪些宏来进行编译(通常情况下,它不会),但等效的C ++ / CLI类型为{ {1}}(注意句柄)。
无论如何,你只需要一个类型为System::Object^
的值初始化项,在C ++中编写为
T