Consider:
struct List(T)
{
private struct Node
{
T payload;
Node* next;
}
private const(Node)* root;
private this(const Node* n)
{
root = n;
}
/**
* Returns a copy of the tail of the list.Complexity $(BIGOH 1).
*/
List tail()
{
assert(root);
auto n = root.next;
return List(n);
}
/// ditto
const(List) tail() const
{
assert(root);
auto n = root.next;
return const(List)(n);
}
inout(List) tail2() inout
{
assert(root);
auto n = root.next;
return inout(List)(n);
}
}
void main()
{
List!(immutable int) lst;
}
The idea is to take the two almost identical (save for the use of the qualifier) functions tail() into one function tail2() that uses inout. Qualifier-independent code has been the main motivation behind the inout qualifier. The compiler issues errors:
struct List(T)
{
private struct Node
{
T payload;
Node* next;
}
private const(Node)* root;
private this(const Node* n)
{
root = n;
}
/**
* Returns a copy of the tail of the list.Complexity $(BIGOH 1).
*/
List tail()
{
assert(root);
auto n = root.next;
return List(n);
}
/// ditto
const(List) tail() const
{
assert(root);
auto n = root.next;
return const(List)(n);
}
inout(List) tail2() inout
{
assert(root);
auto n = root.next;
return inout(List)(n);
}
}
void main()
{
List!(immutable int) lst;
}
test.d(36): Error: mutable method test.List!(immutable(int)).List.this is not callable using a inout object
test.d(42): Error: template instance test.List!(immutable(int)) error instantiating
Comment #1 by dfj1esp02 — 2015-11-03T12:56:11Z
One const method looks enough in your case:
List tail() const
{
assert(root);
auto n = root.next;
return List(n);
}
Comment #2 by andrei — 2015-11-03T14:21:56Z
(In reply to Sobirari Muhomori from comment #1)
> One const method looks enough in your case:
>
> List tail() const
> {
> assert(root);
> auto n = root.next;
> return List(n);
> }
Working around this case is not the point - there are many other cases that don't work.
Comment #3 by robert.schadek — 2024-12-13T18:45:39Z