January 22, 2011
The following code yields results as commented.

import std.stdio;

class A
{
	int b;
}

void main()
{
	const A a = new A;
	writeln(typeof(a).stringof); // const(A)
	writeln(typeof(a.b).stringof); // const(int)

	writeln((const A).stringof); // const(A)
	writeln(typeof((const A).b).stringof); // int
}

Given this information, how do I work around this in templates? I'd like a template which can type its params based on members of T, for instance:

void foo(T)(T x, typeof(T.member) y)

but this will yield non-const second parameters even if T is const. Help anybody?
January 22, 2011
Sean Eskapp wrote:
> The following code yields results as commented.
>
> import std.stdio;
>
> class A
> {
> 	int b;
> }
>
> void main()
> {
> 	const A a = new A;
> 	writeln(typeof(a).stringof); // const(A)
> 	writeln(typeof(a.b).stringof); // const(int)
>
> 	writeln((const A).stringof); // const(A)
> 	writeln(typeof((const A).b).stringof); // int
> }
>
> Given this information, how do I work around this in templates? I'd like a
> template which can type its params based on members of T, for instance:
>
> void foo(T)(T x, typeof(T.member) y)
>
> but this will yield non-const second parameters even if T is const. Help anybody?

Ironically, parameter list is not a useful place to constraint the parameter types. At the least, you probably want some conversions. If so, would this work:

import std.traits;

void foo(T, M)(T x, M m)
    if (isImplicitlyConvertible!(M, typeof(T.member)))
{}

class C
{
    int member;
}

void main()
{
    auto c = new C;
    foo(c, 42);
}

If you want to ensure that the member is assignable, you can try this:

import std.traits;

void foo(T, M)(T x, M m)
    if (__traits(compiles, { x.member = m; }))
{}

class C
{
    int member;
}

void main()
{
    const auto c = new C;  // <-- compilation error
    foo(c, 42);
}

But the error message is only somewhat helpful:

deneme.d(26369): Error: template deneme.foo(T,M) if (__traits(compiles,delegate ()
{
x.member = m;
}
)) does not match any function template declaration
deneme.d(26369): Error: template deneme.foo(T,M) if (__traits(compiles,delegate ()
{
x.member = m;
}
)) cannot deduce template function from argument types !()(const(C),int)

Ali