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

Reply via email to