Can't understand templates
Sly via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Nov 29 03:07:34 PST 2014
On Saturday, 29 November 2014 at 09:11:51 UTC, Ali Çehreli wrote:
> Point!T getResponse(P : Point!T, T)(string question)
> {
> // ...
> }
>
This doesn't work because now this definition has 2 parameters P
and T. I have to specify both like this: auto pt =
getResponse!(Point!int, int)("point"); which of course defeats
the purpose. Otherwise I have ambiguity error:
d.d:73: error: d.getResponse called with argument types (string)
matches both:
d.d(20): getResponse(T)(string question)
and:
d.d(31): getResponse(P : Point!T, T)(string question)
Same thing with specialization for Pair.
Actually what I wrote earlier about C++ is wrong because C++
doesn't allow partial specialization for functions. I wrote this
example in C++ using classes:
template<typename T>
struct Reader {
static T getResponse(const std::string& question) {
std::cout << question << "(" << typeid(T).name() << "):
";
T res;
std::cin >> res;
return res;
}
};
template<typename T>
struct Point {
T x, y;
};
template<typename T>
struct Reader<Point<T>> {
static Point<T> getResponse(const std::string& question) {
std::cout << question << "\n";
Point<T> res;
res.x = Reader<T>::getResponse(" x");
res.y = Reader<T>::getResponse(" y");
return res;
}
};
template<typename A, typename B>
struct Reader<std::pair<A, B>> {
static std::pair<A, B> getResponse(const std::string&
question) {
std::cout << question << "\n";
std::pair<A, B> res;
res.first = Reader<A>::getResponse(" first");
res.second = Reader<B>::getResponse(" second");
return res;
}
};
int main()
{
int i = Reader<int>::getResponse("int");
auto pt = Reader<Point<int>>::getResponse("point");
auto pair = Reader<std::pair<int, int>>::getResponse("pair");
return 0;
}
I translated it literally into D using your syntax and it worked!
class Reader(T) {
public static T getResponse(string question) {
writef("%s (%s): ", question, T.stringof);
T response;
readf(" %s", &response);
return response;
}
}
class Reader(P: Point!T, T) {
public static Point!T getResponse(string question) {
writefln("%s (Point!%s)", question, T.stringof);
auto x = Reader!T.getResponse(" x");
auto y = Reader!T.getResponse(" y");
return Point!T(x, y);
}
}
class Reader(P: Pair!(A, B), A, B) {
public static Pair!(A, B) getResponse(string question) {
writefln("%s (Pair!(%s, %s))", question, A.stringof,
B.stringof);
auto a = Reader!A.getResponse(" a");
auto b = Reader!B.getResponse(" b");
return new Pair!(A, B)(a, b);
}
}
void main()
{
auto i = Reader!int.getResponse("int");
auto pt = Reader!(Point!int).getResponse("point");
auto pair = Reader!(Pair!(int, int)).getResponse("pair");
}
My questions now are:
1. Apparently D has partial specializations of function
templates, but it uses a weird syntax (T: Point!T). How to extend
this syntax for multiple template parameters? (Basically, how to
write this example without wrapping the function into a class?)
2. Why is there a difference between partial specialization of
function templates and class templates: there's a compilation
error with function templates but not with class templates?
More information about the Digitalmars-d-learn
mailing list