Partial specialisation is foobarred?!

Jason House jason.james.house at gmail.com
Sun Aug 16 07:51:25 PDT 2009


FWIW, I usually use static if instead of specialization. In D2, you can also use if expressions as part of the template declaration. As far as your code below, I think the declaration of M without using it is suspect. I don't have a compiler to play with right now...

div0 Wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> I've been poking around on the bug track and can't find a specific bug
> report, but it seems unlikely this hasn't been noticed before.
> 
> This is w/ dmd 2.031 & 1.046
> 
> //========================
> import std.stdio;
> 
> struct nil {
> }
> 
> class D(T) {
>     uint  _len;
>     T	  _val;
> 
>     this(uint l, T v) {	_len = l; _val = v; }
> 
>     // method 0 - to be called with most D!(*)
>     // where only _len is common
>     void f(M)(M rhs) {
>         _len = rhs._len;
>         writefln("method 0");
>     }
> 
>     // method 1 - specalization for D!(nil) types
>     // - set _len to invalid
>     void f(M : D!(nil))(D!(nil) rhs) {
>         _len = cast(uint)(-1);
>         writefln("method 1");
>     }
> 
>     // method 2 - specalization for this type - copy all values
>     // - how many ways we can write this and which is correct?
>     //void f(M : D!(T))(D!(T) rhs) {
>     //void f(M : D!(N), N : T)(D!(T) rhs) {
>     //void f(M : D!(N), N : int)(D!(T) rhs) {
>     void f(M : D!(int))(D!(T) rhs) {
>         _len = rhs._len;
>         _val = rhs._val;
>         writefln("method 2");
>     }
> 
> // we can't do this, it conflicts with template functions
> version(none):
>     void f(D!(T) rhs) {}
> }
> 
> class D(T : nil) {
> }
> 
> int main(char[][]argv) {
>     auto    c0 = new D!(int)(1, 9);
>     auto    c1 = new D!(int)(3, 18);
>     auto    c2 = new D!(nil)();
> 
>     // *should* call method 2, but calls method 0
>     writef("want method 2, getting: ");
>     c0.f(c1);
> 
> version(none) {
>     // *should* call method 1, but calls method 0 which is a
>     // compile error; rather unhelpfully it's an error w/o
>     // giving instantiation line
>     writef("want method 1, getting: ");
>     c0.f!()(c2);
> }
> 
>     // force correct call to method 1
>     writef("want method 1, getting: ");
>     c0.f!(D!(nil))(c2);
> 
>     // try & force correct call to method 2, but fails
>     // (will all 4 sigs), it picks method 0
>     writef("want method 2, getting: ");
>     c0.f!(D!(int))(c1);
> 
>     // interestingly...
>     writef("want method 1, getting: ");
>     c0.f!(typeof(c2))(c2);		// calls method 1
> 
>     // but doesn't work all the time
>     writef("want method 2, getting: ");
>     c0.f!(typeof(c0))(c1);		// calls method 0
> 
>     return 0;
> }
> 
> 
> 
> 
> 
> FYI, the equivalent c++ works fine:
> 
> 
> //========================
> struct nil {
> };
> 
> template< typename T >
> class D {
> public:
>    unsigned _len;
>    T        _val;
> 
>    D(unsigned l, T v) { _len = l; _val = v; }
> 
>    // method 0 - to be called with most D!(*) where only _len is common
>    template< typename M >
>    void f(const M &rhs) {
>       _len = rhs._len;
>       ATLTRACE("method 0\n");
>    }
> 
>    // method 1 - specalization for D!(nil) types - set _len to invalid
>    template<>
>    void f< D<nil> >(const D<nil>& /*rhs*/) {
>       _len = static_cast< unsigned >(-1);
>       ATLTRACE("method 1\n");
>    }
> 
>    // method 2 - specalization for this type - copy all values
>    template<>
>    void f< D< T > >(const D< T >& rhs) {
>       _len = rhs._len;
>       _val = rhs._val;
>       ATLTRACE("method 2\n");
>    }
> };
> 
> template<>
> class D< nil > {
> public:
> };
> 
> void test() {
>    D<int>   c0(1, 9);
>    D<int>   c1(2, 18);
>    D<nil>   c2;
>    D<void*> c3(3, 0);
> 
>    c0.f(c1); // call method 2
>    c0.f(c2); // call method 1
>    c0.f(c3); // call method 0
> }
> 
> - --
> My enormous talent is exceeded only by my outrageous laziness.
> http://www.ssTk.co.uk
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.7 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
> 
> iD8DBQFKh9kDT9LetA9XoXwRAivoAJ9sqIdzPJf1cialdpk8EE9VkBwG7gCbB+l5
> xXxZw9FX80nJjXRa9X2PhDM=
> =Tetp
> -----END PGP SIGNATURE-----




More information about the Digitalmars-d mailing list