Thread overview
Differences between "const Type function()" and "const(Type) function()"
May 30, 2014
bearophile
May 30, 2014
anonymous
May 30, 2014
anonymous
Aug 22, 2014
Théo Bueno
May 30, 2014
Dicebot
May 30, 2014
Today I got the following compile error:
"Cannot implicitly convert expression (<blabla>) of type const(<Type>) to <Type>"
and this is a reduced example ( also on http://dpaste.dzfl.pl/f2f3bd921989):

module test;
import std.stdio;

class Foo {
	int i = 42;	
}

class MyClass {
	private { Foo _Q; }
	this() {_Q = new Foo;}
	Foo getQ () { return _Q; }
	const (Foo) getQ () const { return _Q; } // OK
	// const Foo getQ () const { return _Q; } // fails
}

void main() {
	const MyClass instance = new MyClass;
	writeln(instance.getQ.i);
}

I don't really understand what's going on here. Why is "const Foo getQ()" wrong?
And why is "const(Foo) getQ" so much different? (e.g: this is an explicit cast, right? Is there anything that might go wrong?)
May 30, 2014
francesco cattoglio:

> And why is "const(Foo) getQ" so much different? (e.g: this is an explicit cast, right?

In D the syntax for casts is "cast(something)somethingElse".

Bye,
bearophile
May 30, 2014
On Friday, 30 May 2014 at 12:35:46 UTC, francesco cattoglio wrote:
> class MyClass {
[...]
> 	const (Foo) getQ () const { return _Q; } // OK
> 	// const Foo getQ () const { return _Q; } // fails
> }
[...]
> I don't really understand what's going on here. Why is "const Foo getQ()" wrong?

The "const" in the front is the same as the front in the back.
They both apply to the method, not to the return type. This is
because you can put all method attributes in both places. And the
compiler doesn't seem to care when you repeat them. Maybe it
should.

E.g. `pure void f() pure {}` = `pure void f() {}` = `void f()
pure {}`

> And why is "const(Foo) getQ" so much different? (e.g: this is an explicit cast, right? Is there anything that might go wrong?)

It's not a cast. It's the unambiguous notation for a qualified
type. Often you can omit the parentheses. With methods you
cannot. With methods you need the parentheses to let the compiler
know that you indeed mean the return type to be const, not the
method itself.
May 30, 2014
On Friday, 30 May 2014 at 12:57:52 UTC, anonymous wrote:
> The "const" in the front is the same as the front in the back.

... the same as the "const" in the back
May 30, 2014
On Friday, 30 May 2014 at 12:35:46 UTC, francesco cattoglio wrote:
> Today I got the following compile error:
> "Cannot implicitly convert expression (<blabla>) of type const(<Type>) to <Type>"
> and this is a reduced example ( also on http://dpaste.dzfl.pl/f2f3bd921989):
>
> module test;
> import std.stdio;
>
> class Foo {
> 	int i = 42;	
> }
>
> class MyClass {
> 	private { Foo _Q; }
> 	this() {_Q = new Foo;}
> 	Foo getQ () { return _Q; }
> 	const (Foo) getQ () const { return _Q; } // OK
> 	// const Foo getQ () const { return _Q; } // fails
> }
>
> void main() {
> 	const MyClass instance = new MyClass;
> 	writeln(instance.getQ.i);
> }
>
> I don't really understand what's going on here. Why is "const Foo getQ()" wrong?
> And why is "const(Foo) getQ" so much different? (e.g: this is an explicit cast, right? Is there anything that might go wrong?)

Outcome of terrible decision to apply front `const` to function/method type itself and not return type.
May 30, 2014
On Friday, 30 May 2014 at 12:57:52 UTC, anonymous wrote:
>> And why is "const(Foo) getQ" so much different? (e.g: this is an explicit cast, right? Is there anything that might go wrong?)
>
> It's not a cast. It's the unambiguous notation for a qualified
> type. Often you can omit the parentheses. With methods you
> cannot. With methods you need the parentheses to let the compiler
> know that you indeed mean the return type to be const, not the
> method itself.

Ouch... I even wonder why I wrote about "is this a cast?"... Noob mistake! :P
Anyway thank you everyone, I really thought the two way of writing were equivalent. (it's C++ fault, not mine! I tell you!)
August 22, 2014
On Friday, 30 May 2014 at 12:57:52 UTC, anonymous wrote:
> It's not a cast. It's the unambiguous notation for a qualified
> type. Often you can omit the parentheses. With methods you
> cannot. With methods you need the parentheses to let the compiler
> know that you indeed mean the return type to be const, not the
> method itself.

Please note that outside a class/struct, this notation :

     const T foo()

is meaningless, and before D 2.066 was silently ignored.

Now the compiler will notify you when the error occur, but you
still need to be extra-careful when using const with methods.