C++ Generics issue

Hi.

I'm having a problem converting some C# to C++/CLI,
which involves generics:

//// C# code (compiles and runs): /////////////////////////
// The constraint requires the generic parameter T
// to be convertable to the type of the derived class: public abstract class MyBaseT<T> where T : MyBaseT<T>
{
public MyBaseT()
{
}
} public class MyDerived : MyBaseT<MyDerived>
{
}
//// (equivalent?) C++/CLI code: //////////////////// generic<typename T> where T : MyBaseT<T>
public ref class MyBaseT abstract
{
public:
MyBaseT()
{
}
}; public ref class MyDerived : MyBaseT<MyDerived>
{
};

/// Compiler error: Error 1 error C3393: syntax error in constraint
clause: 'MyBaseT' is not a type (on the first
line of the C++ class declaration).
The C++ compiler doesn't like the generic constraint. Any ideas ?

[970 byte] By [TonyMaresca] at [2007-12-25]
# 1

Hi,

Please look at this: http://msdn2.microsoft.com/en-us/library/a174071k.aspx

Hope this help you.

Thanks.

MNour.AI at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 2

I didn't see anything in that link that resolves the problem.

The problem is that C++/CLI will not allow you to specify a generic constraint on a class which refers to that same class (this is allowed in C# of course).

David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter, VB to C++ converter
Instant Python: VB to Python converter

DavidAnton at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 3
I don't have solution, just two points:
The problem is that C++ compiler requires forward declaration. However, I didn't find a way to make forward declaration - maybe you can do this.
Maybe it is possible to derive MyBaseT from another abstract class, and use this class in constraint. In this case name of base class is known by compiler.
AlexFarber at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 4

I think the following may be as close as you'll get

interface class IMyBaseT
{
};

generic<typename T> where T : IMyBaseT
ref class MyBaseT abstract : IMyBaseT
{
};

ref class MyDerived : MyBaseT<MyDerived^>
{
};

einaros at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 5

Thanks to all for the replies.

I also tried to forward-declare the class but that doesn't appear to work.

I suppose this follows the general behavior of the C++ compiler, which unlike C#, requires any reference to a type to be defined/declared ahead of the reference. I also feel it's a notable flaw in compilation of managed code.

TonyMaresca at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 6

Hello

As mentioned at web page: http://msdn2.microsoft.com/en-us/library/a174071k.aspx , try to use interface in your code.

Thanks.

FatalError at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 7
Which would be exactly what my example proposes :)
einaros at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 8

That's a good solution Einar!

I still find it strange that there's no direct C++/CLI equivalent for this C# code.

David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter, VB to C++ converter
Instant Python: VB to Python converter

DavidAnton at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 9
A bug should be opened on this. Writing a templated base class with the derived class as the parameter is a common thing to do. ATL does this heavily.
BrianKramer at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 10
The problem is in the constraints declaration, though, not the template parameters as such.
einaros at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 11

Brian, do you mean specializations such as

template<typename T>
class Base
{};

template<>
class Base<class Derived>
{
private:
Base();
};

class Derived : Base<Derived>
{};

If so, that's not a problem here. The issue is the constraint, which is declared prior to the class name

generic<typename T> where T : MyBaseT<T>
public ref class MyBaseT abstract

This code yields the error "MyBaseT is not a type" in the constraint clause. In C#, the constraint follows the class name, so it's not an issue there.

I did post a suggestion on what the OP can use as a workaround, but I'm not sure if this is fit for his use. Also, if this problem is "unintentional", a bug report should be opened.

einaros at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 12
I was simply arguing that the compiler not handing this code pattern has high impact. It does appear that parse order is a factor in the compiler not being able to handle it.
BrianKramer at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 13

Ok, then we're on the same page :)

Tony, go to http://connect.microsoft.com/site/sitehome.aspx?SiteID=210 and report your findings there. Be sure to paste a link to the resulting entry.

einaros at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...