Limiting template functions to template instantiations of a struct
simendsjo
simendsjo at gmail.com
Wed Nov 6 05:22:13 PST 2013
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!
}
More information about the Digitalmars-d-learn
mailing list