The following code is the essential part of my program and class to reproduce the failure:
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;
}
When calling func1g, I get a System.TypeLoadException. I just don't understand why.
Is it because func2 does not have a generic parameter?
Here's the full error message (in german, but it just says 'unhandled exception' and 'could not be loaded'; no details):

The equivalent code in C# works:
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;
}
}
I found a kind of 'workaround', see my answer below, but I don't know why this works.
I would appreciate it if someone could explain me the reason of this failure and the function of the workaround.
EDIT 2
In case you want to reproduce this: I use VS 2008 SP1.
I hope that it's not again compiler related like my last issue, although I personally expect this to be very likely...
After some testing, I just found a solution to this specific problem:
I need to define func1g as follows:
generic <class T>
void func1g (T value)
{
...
}
But I don't understand why.
Both ways (the code in the question and this solution) compile fine, but the first way produces a runtime exception, see the post.
One problem is remaining:
Notice that func1g above is declared and defined at the same location!
My original code is separated into .h and .cpp like this:
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 ();
}
Now the compiler complains about the cpp with error C2511: 'void gener<T>::func1g(T)': overloaded member function not found in 'gener<T>'
Therefore I continued playing around (it really was trial and error) and found a working solution, that I absolutely don't understand any more:
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;
}
Can someone explain this to me?
I actually didn't know that a double generic definition was possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With