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