This code compiles and runs just fine
import core.sync.mutex;
import std.stdio;
class FixedList(T){
// list
private T[] list;
// number of items
private size_t numberOfItems;
// capacity
private size_t capacity;
// mutex
private Mutex listMutex;
// get capacity
@property public size_t Capacity(){ return capacity; }
@property public shared size_t Capacity(){ return capacity; }
// constructor
public this( size_t capacity ){
// initialise
numberOfItems = 0;
this.capacity = capacity;
writeln("Cons Normal");
}
// constructor
public shared this( size_t capacity ){
// initialise
numberOfItems = 0;
this.capacity = capacity;
// create mutex
listMutex = cast(shared)(new Mutex());
writeln("Cons Shared");
}
}
void main()
{
auto list1 = new shared FixedList!int( 128 );
auto list2 = new FixedList!int( 128 );
}
as it should. But if you comment out the calls to writeln (making the constructors pure), then you get this compilation error
q.d(45): Error: called with argument types:
(int) shared
matches both:
q.d(22): q.FixedList!int.FixedList.this(ulong capacity)
and:
q.d(31): q.FixedList!int.FixedList.this(ulong capacity)
q.d(45): Error: no constructor for FixedList
because the compiler can now use either constructor to construct a shared object thanks to the fact that it knows that the constructors will return unique objects. So, this the usability improvement of making pure constructors able to construct shared or immutable objects is biting us here.
I would suggest that in cases where one of the constructors can construct a shared (or immutable) object thanks to its purity and a constructor which is explictly shared (or immutable) exists, the one which is explicitly shared (or immutable) should take precedence.