www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - static opCall 'hidden' by incompatible constructors

reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
Hi,
I'm trying to update std.typecons.Unique. I want to add a static opCall 
with no arguments to simulate a nullary-argument constructor. 
Unfortunately, with a recent dmd from Git, I get this (reduced code):

class Class {}

struct U
{
     Class c;

     this(A...)(A args)
     if (A.length != 0)
     {
         c = new Class(args);
     }

     static U opCall()
     {
         U u;
         u.c = new Class;
         return u;
     }
}

$ c:\git\digger\current\bin\dmd -w -c "opcall.d" -g -gc -unittest
opcall.d(24): Error: struct opcall.U static opCall is hidden by 
constructors and can never be called
opcall.d(24):        Please use a factory method instead, or replace all 
constructors with static opCall.

This is a new error in the next release. It seems to be this bug, marked 
as WONTFIX:
https://issues.dlang.org/show_bug.cgi?id=12194

As nullary static opCall doesn't conflict with a nullary constructor (as 
the latter can't exist), it would be useful to allow it. Otherwise, how 
can we wrap the construction of a class with a nullary constructor?
Jul 17 2014
next sibling parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 17/07/2014 18:11, Nick Treleaven wrote:
 opcall.d(24): Error: struct opcall.U static opCall is hidden by
 constructors and can never be called
 opcall.d(24):        Please use a factory method instead, or replace all
 constructors with static opCall.
I should mention that std.typecons.Unique needs other constructors as well, so I can't use static opCall alone. Maybe using a factory method would work, but I think it would either be inconsistent to mix factory method + other ctors or cumbersome to only use a factory method.
Jul 17 2014
parent reply "Kagamin" <spam here.lot> writes:
Try to define a constructor with parameters, then compiler won't 
generate the default constructor, so the parameterless opCall 
won't be hidden.
Jul 19 2014
parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 19/07/2014 10:32, Kagamin wrote:
 Try to define a constructor with parameters, then compiler won't
 generate the default constructor, so the parameterless opCall won't be
 hidden.
That only works for classes, not structs.
Jul 20 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Thursday, 17 July 2014 at 17:11:29 UTC, Nick Treleaven wrote:
 I want to add a static opCall with no arguments to simulate a 
 nullary-argument constructor.
Please don't do it unless you have a _very_ compelling use case.
 As nullary static opCall doesn't conflict with a nullary 
 constructor (as the latter can't exist), it would be useful to 
 allow it. Otherwise, how can we wrap the construction of a 
 class with a nullary constructor?
It has never worked properly (opCall never got called) and being a bad style going against language design rationale it was completely banned. More info: https://issues.dlang.org/show_bug.cgi?id=12124 I believe CTFE-only default struct constructors should be allowed instead but until this becomes an option, having factory functions is the way to go ("auto var = unique(new T)" vs "Unique!T var = new T") I am pretty sure many D users will disagree though :)
Jul 17 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
(for Unique probably disabling default constructor makes most 
sense)
Jul 17 2014
parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 17/07/2014 18:58, Dicebot wrote:
 (for Unique probably disabling default constructor makes most sense)
I'm not sure about that, default construction is useful to be able to delay resource creation: Unique!S u1; ... u1 = unique!S(); // factory function To allow that but disallow Unique!S(), maybe we'd need this: disable static opCall(); (That doesn't compile ATM).
Jul 18 2014
prev sibling parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 17/07/2014 18:56, Dicebot wrote:
 It has never worked properly (opCall never got called) and being a bad
 style going against language design rationale it was completely banned.
 More info: https://issues.dlang.org/show_bug.cgi?id=12124
Thanks for the link. We need a note in the changelog about that IMO.
 I believe CTFE-only default struct constructors should be allowed
I'll just point out that I don't want *default* struct constructors, I understand the T.init issue. I want nullary constructor syntax that is called explicitly with brackets.
 instead but until this becomes an option, having factory functions is
 the way to go ("auto var = unique(new T)" vs "Unique!T var = new T")
OK.
Jul 18 2014