Best way of checking for a templated function instantiation

Meta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 10 06:37:47 PDT 2016


On Wednesday, 10 August 2016 at 12:36:14 UTC, Arafel wrote:
> Hi,
>
> I'm trying to check at compilation time if a given type 
> implements some operator (let's assume it's '+' in this case), 
> without caring about the type of the parameters it accepts. 
> Since operator overloading is expressed in D through templated 
> functions, what is the preferred way of checking if a template 
> is / can be instantiated with a given parameter list?
>
> So far I've come with a solution using __trait(compiles, ...), 
> but perhaps it's not 100% reliable -I'm no expert in template 
> wizardry-, or there are better options. I also tried with 
> hasMember, but it apparantly only shows that "opBinary" is 
> indeed present, but nothing more:
>
> ---
> void main() {
> 	struct S {
> 		int opBinary(string op)(int i) if (op == "+") {
> 			return 0;
> 		}
> 	}
>
> 	static assert(__traits(compiles, S.opBinary!"+"));
> 	static assert(!__traits(compiles, S.opBinary!"-"));
> }
> ---

__traits(compiles) is pretty much the only way to do it. For 
example, if you want to check that S supports opBinary!"+"(int):

static assert(__traits(compiles, auto _ = 
S.init.opBinary!"+"(int.init));

And if you want to check that the return type is int or 
implicitly converts to int, you can change the `auto _ = ...` to 
`int _ = ...`. However, if you want to be more explicit about it, 
you can do the following:

import std.traits;

static assert(is(ReturnType!(S.opBinary!"+") == int)); //Change 
to `... : int` for implicit conversion checking


More information about the Digitalmars-d-learn mailing list