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