The key is to use a constraint with an auxiliary function:
enum MyUDA;
struct A {
@MyUDA int a1;
@MyUDA float a2;
}
struct B {
@MyUDA string b;
}
void main() {
A a;
B b;
foo( a );
foo( b );
}
template HasMyUDA(T) {
static bool helper() {
foreach(memberName; __traits(allMembers, T)) {
foreach(attr; __traits(getAttributes, __traits(getMember, T, memberName)))
static if(is(attr == MyUDA))
return true;
}
return false;
}
enum HasMyUDA = helper();
}
void foo(T)(T t) if(HasMyUDA!T) {
pragma(msg, T.stringof ~ " works here");
}
, -, , , .