Bug 11947 – std.typecons.Proxy incorrectly handles variadic member templates
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-01-19T01:41:15Z
Last change time
2019-12-21T08:09:07Z
Keywords
pull
Assigned to
No Owner
Creator
Stanislav Blinov
Comments
Comment #0 by stanislav.blinov — 2014-01-19T01:41:15Z
When forwarding member function calls, Proxy incorrectly handles cases when member template is variadic:
import std.typecons : Proxy;
struct RealThing {
void variadic(T...)(T args) {}
}
struct Impostor {
private RealThing p;
mixin Proxy!p;
}
void main()
{
Impostor test;
test.variadic(); // ok
test.variadic("hello"); // error instantiating
}
Proposed solution:
// Original (std.typecons@3884):
// member template
template opDispatch(T...)
{
auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~"!T(args)"); }
}
// Change to (std.typecons@3884):
// member template
template opDispatch(T...)
{
auto ref opDispatch(this X, Args...)(auto ref Args args)
{
// T is empty, deduction is in effect
static if (Args.length) { return mixin("a."~name~"!"~Args.stringof~"(args)"); }
// T is explicitly specified
else { return mixin("a."~name~"!T(args)"); }
}
}
Comment #1 by stanislav.blinov — 2014-01-20T08:18:31Z
Proxy's opCall() seems to exhibit similar issue, when using getter property as proxy:
struct RealThing {
void opCall(T...)(T args) {}
}
struct Impostor {
private RealThing p;
private @property RealThing* get() { return &p; }
mixin Proxy!get;
void opCall(T...)(T args) {}
}
void main() {
Impostor imp;
imp(); // ok
imp("hello"); // error instantiating
}
Proposed solution (explicitly call opCall):
// Original (std.typecons@3817):
auto ref opCall(this X, Args...)(auto ref Args args) { return a(args); }
// Change to (std.typecons@3817):
auto ref opCall(this X, Args...)(auto ref Args args) { return a.opCall(args); }
Comment #2 by stanislav.blinov — 2014-01-20T22:48:49Z
(In reply to comment #1)
> struct Impostor {
> private RealThing p;
> private @property RealThing* get() { return &p; }
> mixin Proxy!get;
>
> void opCall(T...)(T args) {}
> }
Uh, sloppy copy, sorry about that. Impostor should not have that opCall at all, only RealThing should.
Comment #3 by stanislav.blinov — 2014-02-08T14:53:39Z