0

I read some complex template class design, it looks like recirsive template deduction with template parameter refers to the template itself. I simplified the codes as follow, does anybody can help explain how the template deduction works for the follow codes. also I want to know more knowledge about the programming technique used in this demo and can you share me any c++ standard material about this topic.

#include <iostream>

template<typename X = char, class T = int>
class ABC;

template<class X, class T>
class ABC <X, ABC<X, T>>{
public:
    T t;
};


template<class T, class M>
class ABC : public ABC<T, ABC<T,M>> {};

int main() {
    ABC<int, char> abc;
    abc.t = 1;
    ABC<> abcd;
    abcd.t = 3;
    std::cout << abc.t << " " << abcd.t << std::endl;
}

as shown above, I tried simplified the code and write a little demo. my compiler is gcc 9.4.0 released with ubuntu20, with compile args -std=c++17.

What I concerned most is how abc or abcd is deduced as ABC<T, M> is inherited from ABC<T, ABC<T, M>>, and ABC<T, M> seems is a self-referencing template class?

And also how the template deduction terminated as it seems there is only a template class declaration template<typename X = char, class T = int> class ABC; and seems no implemention of it.

abc.t is print as unvisable char succeeding with a whitespace and then a charater 3, as below.

 3
Jerry2102
  • 1
  • 2
  • 2
    There is no "template deduction" of any kind going on here. – Nicol Bolas Feb 06 '23 at 05:18
  • 1
    You simplified some complex looking code. Please show the complex looking code. Your code doesn't make much sense to me. – kiner_shah Feb 06 '23 at 05:26
  • Your code is equivalent to `std::cout << char(1) << " " << int(3)`. as `abc.t` is of type `char`. In other words, you are printing an unprintable ASCII character; that's why you can't see it in the output. Make it `abc.t = '!'`;` and you'll [see it printed](https://godbolt.org/z/98sxq5j3a) – Igor Tandetnik Feb 06 '23 at 05:41
  • OK, thanks a lot about explanation about the printed whitespace caused by char. But the problem I concerned more is how ABC is deduced. it seems there is a self-referring template class ABC and a inherited template class also called ABC – Jerry2102 Feb 06 '23 at 06:22
  • This is just partial specialization... You first have a primary template declaration, then a partial specialization of that template, then the primary template definition. There is no recursion taking place. – ildjarn Feb 06 '23 at 06:34
  • @ildjarn How is a template using itself as a type parameter (`template class ABC >`) not recursive? – Peter - Reinstate Monica Feb 06 '23 at 06:41
  • I also wondering why template class ABC > {}; is not a self-referencing recursive template? now I understand that templateclass ABC is a subclass(with template parameters not deduced) of the partial specialized template class ABC>, but how template class ABC > {}; works properly – Jerry2102 Feb 06 '23 at 06:56
  • @Peter : The primary template is not using itself as a type parameter – it is unconditionally using the partial specialization, which is effectively a different template (it has a different definition after all). – ildjarn Feb 06 '23 at 10:03
  • @ildjarn That may all be true, but isn't `template class ABC >` recursive? – Peter - Reinstate Monica Feb 06 '23 at 12:22
  • @Peter : Again, no, that is simply a specialization for cases where the 2nd template argument supplied happens to itself be an `ABC`. This is closer to pattern matching than recursion (but is not strictly 'matching' because partial ordering is a thing). `std::pair>` is not recursion either. – ildjarn Feb 06 '23 at 12:29
  • @ildjarn I got another question, is ABC deduced from the partial specialized template, or is it deduced from the primary template? If it is deduced from the primary version, we got a ABC who is a subclass of ABC> and ABC is deduced from the partial specialized template with X=int and T=char, so the partial specialized template is instantiate to template<> ABC> {char t;}; Is that right? – Jerry2102 Feb 06 '23 at 14:05
  • `ABC` instantiates the primary template (whose declaration is on line 3-4 of your code and whose definition is on line 13-14); the primary template inherits from the partial specialization, in this case `ABC>`. So I think your understanding is correct, it's just terminology that is a problem – as was said by others, there is no deduction taking place here, so continuing to ask about what is "deduced" is only confusing things. – ildjarn Feb 06 '23 at 14:14
  • @ildjarn thanks a lot for your rigorous explanation. I indeed got confused with deduction and instantiation and now I will make my understanding about instantiation and deduction. – Jerry2102 Feb 07 '23 at 02:45

0 Answers0