eldiener wrote: |
Holger Grund wrote: |
Effectively, C++ native references translate to native pointers in CLR speak. It is perfectly possible to have a native pointer to an object of a generic parameter type. However, as you've probably noticed by now there are a lot of things in VC++'s CLR support that are less than perfect. | |
By "native pointers" do you mean "T *" or "T ^"
| |
Neither :-) As I've said it is a CLR term. V%, R^%, interior_ptr, pin_ptr (but not R%) all translate to managed pointers (which to further confusion are named with "&" in ILASM).
eldiener wrote: |
The problem in generic classes is that one can not have a member function that is T ^. The obvious reason for this is that T itself may be a ref class so that T ^ now becomes T ^ ^, which is impossible. That would be fine if one could than have T % as an alias for whatever T is. But even that is forbidden, for all CLR classes, which was the point of my OP.
| |
There are some asymmetries in the semantics of ^ and %. R^ and R% both are object references. For value types, however, V^ is a boxed value type and hence an object reference. While V% is a managed pointer.
However, as I understand your problem you don't want R% but R^%. That works just fine:
Code Snippet
generic void foo( T% t ) {} // t is always a tracking reference - it cannot be R%
eldiener wrote: |
If in native C++ one can have a reference to any object as an alias for that object anywhere, it seems to me a great limitation of the CLR that one can not have a "reference" to any CLR object as an alias to that object anywhere. By "reference" in CLR I mean a tracking reference, %, in C++/CLI or the 'ref' keyword in C#.
| |
Yes that's understood. I don't know the rationale for not allowing managed pointers as members. I suspect it has something to do with GC.
eldiener wrote: |
I am not sure if what you are mentioning as "managed pointers" is what I mention as "tracking references" but I will assume it is.
| |
Yes pretty much, as I mentioned earlier.
eldiener wrote: |
I will play around with pinning pointers in a generic class, as you suggested, but I have small hope this will work.
| |
Why Brandon Bray said they dismissed the notion of "managed pointers" I of course do not know, or what "stackonly" types have to do with it, unless a member function of a class is considered "stackonly". I do realize that tracking references are more complicated than C++ native references, since tracking references can be rebound, and maybe this has something to do with the reason that the notion of tracking references as members of classes was dismissed. Of course, just like C++ native references I would say that tracking references as members of classes, if it had been accepted, would have to be set to some actual object upon object instantiation.
| |
What it was asking for is something along the lines of:
Code Snippet
template<typename T>
auto value struct reference_wrapper { explicit reference_wrapper( T% t ) : t_ (t) {} ~reference_wrapper() { t_ = T(); } // yes - value types could have SMFs back then
private:
T% t_;
};
Instances of these "auto" classes could only ever have automatic storage duration and hence the compiler frontend could move the data members to the local scope, consequently overcoming the limitation of managed pointers cannot be members. I've never seen any concrete syntax, but apparently it was discussed at some point and called "stackonly" types. However, the idea was not taken further.
If you really, insist on something like this you can probably use a combination of generic dispatch,interfaces that should at the very least work for locals. |