On Wednesday, 6 November 2013 at 13:00:17 UTC, Atila Neves wrote:
The title isn't very clear but I wasn't sure how to phrase it
without code. Basically what I want to do is this (won't
compile):
struct Foo(int N) {
}
void func(T)(T obj) if(is(T:Foo)) {
}
void func(T)(T obj) if(!is(T:Foo)) {
}
Foo by itself isn't a type, but I don't want to limit func
instantiation in the 1st case to just e.g. Foo!3 but to _any_
Foo regardless of N. I came up with two workarouds: make Foo a
class that derives from an empty FooBase (then is(T:FooBase)
works), or adding a "secret" enum within Foo that I can check
with std.traits.hasMember in a static if. I don't really like
either of them. Is what I want to do possible?
Atila
Here's a couple of different ways to do this.
import std.stdio;
struct Foo(int N) {
}
void func(T)(T obj) if(is(T:Foo!U, int U)) {
writeln("It's a Foo!");
}
void func(T)(T obj) if(!is(T:Foo!U, int U)) {
writeln("No Foo :(");
}
template isFoo(T) {
static if(is(T:Foo!U, int U))
enum isFoo = true;
else
enum isFoo = false;
}
void gunc(T)(T obj) if(isFoo!T) {
writeln("Gunc isFoo");
}
void gunc(T)(T obj) if(!isFoo!T) {
writeln("Gunc !isFoo");
}
void hunk(T)(T obj) {
static if(isFoo!T)
writeln("Hunk!");
else
writeln("No hunk!");
}
void main() {
Foo!3 f;
func(f); // It's a Foo!
struct S {}
S s;
func(s); // No Foo :(
gunc(f); // Gunc isFoo
gunc(s); // Gunc !isFoo
hunk(f); // Hunk!
hunk(s); // No hunk!
}