1

So I was learning template meta programming and came across a declaration like this.

template<class> struct S;
template<class R, class...A> struct S<R(A...)>;

So I was wondering what are the different ways to specify the typenames in angular brackets after identifier. So I tried different combinations of declaring a structure. I tried googling but that didn't solve this issue as I didn't know what to google exactly. Or if there's a resource(blog, SO Answer) for this, please point me to it.

template<class> struct S;
// template<class A> struct S<A>; // 1. does not work
// template<class A, class B> struct S<A, B>; // 2. does not work
template<class A, class B> struct S<A(B)>;
template<class A, class ... B> struct S<A(B...)>;
template<class A, class ... B, class C> struct S<A(B..., C)>;
template<class A, class B, class ... C> struct S<A(B, C...)>;
template<class A, class ... B, class ... C> struct S<A(B..., C...)>;
template<class A, class ... B, class ... C, class D> struct S<A(B..., D, C...)>;

// template<class A, class ... B> struct S<B..., A>; // 3. does not work
// template<class A, class ... B> struct S<A, B...>; // 4. does not work
template<class A, class B, class C, class D> struct S<A(B(C(D)))>;
template<class A, class B, class C, class D> struct S<A(B(C, D))>;
template<class A, class B, class C, class D> struct S<A(B, C(D))>;
template<class A, class B, class C, class D> struct S<A(B(D), C)>;
template<class A, class B, class C, class D> struct S<A(B, C, D)>;

int main() {
    return 0;
}
Anubhav Gupta
  • 421
  • 5
  • 12
  • 2
    The second template declaration is a specialization. Running search engine queries is not a very productive way to learn C++, especially advanced concepts like template specialization. No "resource(blog, SO Answer)" is a replacement for a [good C++ textbook](https://stackoverflow.com/questions/388242/), neither is a search engine; and asking for recommendation is not an appropriate question here, anyway. – Sam Varshavchik Dec 13 '22 at 20:48
  • 2
    What you are dealing with is called partial template specialization – NathanOliver Dec 13 '22 at 20:49
  • A lot of these are just different function types with different parameter and return types. There are an infinite number of function types. – chris Dec 13 '22 at 21:02
  • 2
    Your base template `template struct S;` states that `S` takes one template parameter. Then `1.` fails because it is exactly the same as the base template. `2.`, `3.`, and `4.` fail because they **don't** take one parameter, so doesn't match the base template. – BoP Dec 13 '22 at 21:23
  • *"I was wondering what are the different ways to specify the typenames in angular brackets after identifier."* -- This strikes me as an unproductive approach. You are looking at what syntax is allowed, rather than at what the syntax means. While knowing syntax is useful, it is not in itself a useful goal (most of the time -- few things are 100%). Better would be to seek to understand what `struct S` means. Words without meaning might be full of sound and fury, yet signify nothing. Code without semantics might compile, yet accomplish nothing. – JaMiT Dec 13 '22 at 22:06
  • Thanks @BoP for this concise explanation – Anubhav Gupta Dec 14 '22 at 08:34

1 Answers1

1

Good sources to learn C++ are learncpp.com which is a tutorial collection and of course cppreference.com, the full language and standard library reference.

template<class> struct S;
template<class R, class...A> struct S<R(A...)>;

The first line is a template class declaration. The second line is a specialization of this template, in case the type S is a function that receives any number of arguments of any type, and returns any type R.

#include <iostream>

// standard implementation
template<class>
struct S {
    static constexpr auto value = 1;
};

// full specialization
template <>
struct S<bool> {
    static constexpr auto value = 2;
};

// partitial specialization for all functions
template<class R, class ... A>
struct S<R(A...)> {
    static constexpr auto value = 3;
};

int main(){
    std::cout << S<int>::value << " S<int>::value\n";
    std::cout << S<float>::value << " S<float>::value\n";
    std::cout << S<bool>::value << " S<bool>::value\n";
    std::cout << S<void()>::value << " S<void()>::value\n";
    std::cout << S<int()>::value << " S<int()>::value\n";
    std::cout << S<int(float, char, bool)>::value << " S<int(float, char, bool)>::value\n";
}

does print

1 S<int>::value
1 S<float>::value
2 S<bool>::value
3 S<void()>::value
3 S<int()>::value
3 S<int(float, char, bool)>::value
Benjamin Buch
  • 4,752
  • 7
  • 28
  • 51