On Wednesday, August 10, 2016 12:36:14 Arafel via Digitalmars-d-learn 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!"-")); > } > ---
I'd advise against checking for opBinary in general, because it'll only work with user-defined types, whereas a built-in type may define the operator. It's usually better to test that the operator works rather than that opBinary exists. So, you end up with checks like __traits(compiles, lhs + rhs) or __traits(compiles, T.init + T.init). If you're picky about the return type, you can do stuff like __traits(compiles, T t = T.init + T.init) (that might require braces around the statement along with a semicolon; I don't remember). If you test for it enough, you can create an eponymous template that wraps the test so that you just have to do something like hasAdd!T or hasBinaryOp!("+", T). That's basically what you get with traits like isInputRange. They're eponymous templates that wrap tests that use is(typeof(...)) or __traits(compiles, ...) to test that a particular block of code or expression compiles, but wrapping that in an eponymous template makes it more idiomatic and makes it so that you don't have to duplicate the implementation of the check everywhere (which is important if the check isn't simple). - Jonathan M Davis