Re: Template constraints for reference/value types?
On Wednesday, 7 September 2016 at 00:40:27 UTC, Jonathan M Davis wrote: On Tuesday, September 06, 2016 21:16:05 Jon Degenhardt via Digitalmars-d-learn wrote: On Tuesday, 6 September 2016 at 21:00:53 UTC, Lodovico Giaretta wrote: > On Tuesday, 6 September 2016 at 20:46:54 UTC, Jon Degenhardt > > wrote: >> Is there a way to constrain template arguments to reference >> or value types? I'd like to do something like: >> >> T foo(T)(T x) >> >> if (isReferenceType!T) >> >> { ... } >> >> --Jon > > You can use `if(is(T : class) || is(T : interface))`. > > If you also need other types, std.traits contains a bunch of > useful templates: isArray, isAssociativeArray, isPointer, ... Thanks. This looks like a practical approach. It'll get you most of the way there, but I don't think that it's actually possible to test for reference types in the general case [snip] - Jonathan M Davis Thanks, very helpful. I've concluded that what I wanted to do isn't worth pursuing at the moment (see the thread on associative arrays in the General forum). However, your description is helpful to understand the details involved.
Re: Template constraints for reference/value types?
On Tuesday, September 06, 2016 21:16:05 Jon Degenhardt via Digitalmars-d-learn wrote: > On Tuesday, 6 September 2016 at 21:00:53 UTC, Lodovico Giaretta > > wrote: > > On Tuesday, 6 September 2016 at 20:46:54 UTC, Jon Degenhardt > > > > wrote: > >> Is there a way to constrain template arguments to reference or > >> value types? I'd like to do something like: > >> > >> T foo(T)(T x) > >> > >> if (isReferenceType!T) > >> > >> { ... } > >> > >> --Jon > > > > You can use `if(is(T : class) || is(T : interface))`. > > > > If you also need other types, std.traits contains a bunch of > > useful templates: isArray, isAssociativeArray, isPointer, ... > > Thanks. This looks like a practical approach. It'll get you most of the way there, but I don't think that it's actually possible to test for reference types in the general case - the problem being structs with postblit constructors. In many cases, it's possible to detect that a struct has to be a value type, and it's often possible to detect that a struct is a reference type (by looking at the types of the member variables in both cases), but as soon as postblit constructors get involved, it's not possible anymore, because the exact semantics depend on the implementation of the postblit constructor. For instance, struct S { int* i; } is clearly a reference type, but struct S { this(this) { ... } int* i; } may or may not be one. In this particular case, the postblit constructor _probably_ does a deep copy of the member variables, but it might also just print out that the postblit constructor was called or do some other non-obvious thing that the person who wrote it thought that it should do. So, there will be some types where you cannot determine whether they're reference types or value types. And that doesn't even take into consideration types like dynamic arrays or structs like this struct S { int* i; byte b; } which are pseudo-reference types, because part of their state is local and part of it is on the heap. So, depending on what you're trying to do, checking for classes, interfaces, and pointers may get you what you're looking for, and you can get really fancy with trying to determine whether a struct might be a value type or reference type if that suits your purposes, but you're not going to determine the copy semantics of all types. You can figure it out for a lot of them though. - Jonathan M Davis
Re: Template constraints for reference/value types?
On Tuesday, 6 September 2016 at 21:00:53 UTC, Lodovico Giaretta wrote: On Tuesday, 6 September 2016 at 20:46:54 UTC, Jon Degenhardt wrote: Is there a way to constrain template arguments to reference or value types? I'd like to do something like: T foo(T)(T x) if (isReferenceType!T) { ... } --Jon You can use `if(is(T : class) || is(T : interface))`. If you also need other types, std.traits contains a bunch of useful templates: isArray, isAssociativeArray, isPointer, ... Thanks. This looks like a practical approach.
Re: Template constraints for reference/value types?
On Tuesday, 6 September 2016 at 20:46:54 UTC, Jon Degenhardt wrote: Is there a way to constrain template arguments to reference or value types? I'd like to do something like: T foo(T)(T x) if (isReferenceType!T) { ... } --Jon You can use `if(is(T : class) || is(T : interface))`. If you also need other types, std.traits contains a bunch of useful templates: isArray, isAssociativeArray, isPointer, ...
Template constraints for reference/value types?
Is there a way to constrain template arguments to reference or value types? I'd like to do something like: T foo(T)(T x) if (isReferenceType!T) { ... } --Jon