Disabling opAssign in a type disabled all the opAssigns of an aliased type?
Simen Kjærås
simen.kjaras at gmail.com
Mon Jul 30 20:54:28 UTC 2018
On Monday, 30 July 2018 at 18:30:16 UTC, aliak wrote:
> Is this a bug?
>
> If not is there a workaround?
>
> I would like for the alias this to function as a normal A type
> unless B specifically disables certain features, but it seems
> weird that disabling one opAssign disables all of them inside
> the aliases type but not in the aliasing type?
>
>
> struct A {
> void opAssign(int) {}
> }
> struct B {
> A a;
> alias a this;
> @disable void opAssign(float);
> }
>
> void main() {
> B b;
> b = 3;
> }
>
> Error: function `onlineapp.B.opAssign` is not callable because
> it is annotated with @disable
The workaround is to not disable opAssign. :p
Since this does work for other member functions that opAssign,
I'm gonna say it's a bug - please file it in Bugzilla.
A perhaps better workaround than the above is to wrap A's
opAssigns. Sadly, this can't be done with template mixins, since
they don't overload with non-mixins. It can be done with string
mixins, however. It's also possible to encapsulate all this in a
nice little template:
struct A {
void opAssign(int) {}
void opAssign(float) {}
}
struct B {
A a;
alias a this;
@disable void opAssign(float);
mixin(wrap!(B, "opAssign"));
}
string wrap(T, string methodName)() {
enum targetName = __traits(getAliasThis, T)[0];
return `import std.traits : Parameters, ReturnType;
static foreach (e; __traits(getOverloads,
typeof(`~targetName~`), "`~methodName~`"))
static if (!is(typeof({static assert(__traits(isDisabled,
getOverload!(typeof(this), "`~methodName~`", Parameters!e)));})))
ReturnType!e `~methodName~`(Parameters!e args) {
return __traits(getMember, `~targetName~`,
"`~methodName~`")(args);
}`;
}
template getOverload(T, string name, Args...) {
import std.traits : Parameters;
import std.meta : AliasSeq;
template impl(overloads...) {
static if (overloads.length == 0) {
alias impl = AliasSeq!();
} else static if (is(Parameters!(overloads[0]) == Args)) {
alias impl = overloads[0];
} else {
alias impl = impl!(overloads[1..$]);
}
}
alias getOverload = impl!(__traits(getOverloads, T, name));
}
unittest {
B b;
b = 3;
static assert(!__traits(compiles, b = 3f));
}
And that's enough magic for me for one night.
--
Simen
More information about the Digitalmars-d-learn
mailing list