Partial specialisation is foobarred?!
div0
div0 at users.sourceforge.net
Sun Aug 16 03:01:39 PDT 2009
-----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