www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What am I missing? Pure constructor behaves differently when assigning

reply "jostly" <johan.f.ostling gmail.com> writes:
I can't find a way to use a pure constructor to create both 
mutable and immutable instances of the same class, when one of 
the fields I assign is a string.

This works fine:
	class A
	{
		int value;
		
		this(int value_) pure
		{
			this.value = value_;
		}	
	}
	
	auto a_mutable = new A(1);
	auto a_immutable = new immutable A(2);

But if I change the field to a string, I get a compilation error:
	class B
	{
		string value;
		
		this(string value_) pure
		{
			this.value = value_;
		}	
	}
	
	auto b_mutable = new B("foo");
	auto b_immutable = new immutable B("bar");

giving a compilation error for the last row:

Error: mutable method B.this is not callable using a immutable 
object

forcing me to use two separate constructors, which works fine:
	class B
	{
		string value;
		
		this(string value_)
		{
			this.value = value_;
		}	

		this(string value_) immutable
		{
			this.value = value_;
		}	
	}

The question is: am I missing something that would make it 
possible to use a pure constructor in this case, or is it simply 
not possible?
Nov 29 2014
next sibling parent "jostly" <johan.f.ostling gmail.com> writes:
On Saturday, 29 November 2014 at 09:41:00 UTC, jostly wrote:
 I can't find a way to use a pure constructor to create both 
 mutable and immutable instances of the same class, when one of 
 the fields I assign is a string.
After poking around a bit, I believe it is caused by issue #10012 https://issues.dlang.org/show_bug.cgi?id=10012 : "This is current dmd implementation limitation. In complex cases dmd cannot detect that the constructor generates unique object." So my question then becomes, how can I generate an unique object from the string? I tried using .idup on the incoming string, but that didn't help. Or is it simply still a problem of _detecting_ it for the compiler?
Nov 29 2014
prev sibling parent "anonymous" <anonymous example.com> writes:
On Saturday, 29 November 2014 at 09:41:00 UTC, jostly wrote:
 I can't find a way to use a pure constructor to create both 
 mutable and immutable instances of the same class, when one of 
 the fields I assign is a string.
[...]
 The question is: am I missing something that would make it 
 possible to use a pure constructor in this case, or is it 
 simply not possible?
I ran some tests, as far as I can tell, they should all work: mixin template test(T) { class C { T value; this(T value_) pure {this.value = value_;} } static assert(is(typeof({auto c = new C(T.init);}))); static if(!is(typeof(new immutable C(T.init)))) pragma(msg, T, ": immutable construction fails"); static if(!is(typeof({immutable c = new C(T.init);}))) pragma(msg, T, ": unique construction fails"); } /* No indirections (and no (d/w)char): all fine */ mixin test!int; mixin test!(int[3]); /* With indirections: immutable construction fails unique construction works */ mixin test!string; mixin test!(immutable int[]); mixin test!(immutable Object); mixin test!(immutable int*); /* No indirections, but (d/w)char: immutable construction works unique construction fails Wat. */ mixin test!dchar; mixin test!wchar; mixin test!char; mixin test!(dchar[3]);
Nov 29 2014