1

I would like to know how to make a template with an own class:

#include <iostream>
using namespace std;

template<C cc> void A()
{
    cout << cc.l << endl;
}

int main()
{
    C cc;
    A<cc>();
}

class C
{
public:
    int l = 10;
};

But it doesn't work, so how to use that class, like a non-generic class parameter, like here:

#include <iostream>
using namespace std;

template<int i> void A()
{
    cout << i << endl;
}

int main()
{
    A<100>();
}
Wulgryn
  • 41
  • 7

1 Answers1

8

You can do it as shown below with C++20(&onwards):

//moved definition of C before defining function template `A`
struct C 
{
    int l = 10;
};
template<C cc> void A()
{
    cout << cc.l << endl;
}

int main()
{
//--vvvvvvvvv--------->constexpr added here
    constexpr C cc;
    A<cc>();
}

Working demo


Two changes have been made:

  1. As template arguments must be compile time constant, constexpr is used.

  2. The definition of C is moved before the definition of function template.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • 1
    The other change you made is worth to be mentioned as well: To use `class C` as non-type template parameter, it has to be defined before-hand. Otherwise the `template` complains about undefined type. (An incomplete type is not sufficient as well.) – Scheff's Cat Jul 13 '22 at 08:35
  • 1
    @Scheff'sCat Added that in my updated answer. – Jason Jul 13 '22 at 08:36
  • It sais: C7592 a non-type template-parameter of type 'C' requires at least '/std:c++20' How to view or change the code version? – Wulgryn Jul 13 '22 at 08:37
  • @Wulgryn Yes, the program will only work with C++20 and onwards. It is mentioned in the first statement of my answer. – Jason Jul 13 '22 at 08:38
  • 1
    @Wulgryn Do you mean that you want the program to work with prior C++20? If yes, then it is not possible as nontype template parameters of literal class type is only allowed from C++20 as can be seen [here](https://en.cppreference.com/w/cpp/language/template_parameters). – Jason Jul 13 '22 at 08:39
  • I changed to C++20, and it's working, but is there a way to work with the 'class' keyword? – Wulgryn Jul 13 '22 at 08:44
  • @Wulgryn Yes `class` keyword can be used. See [demo](https://onlinegdb.com/TN_VEoVoC) – Jason Jul 13 '22 at 08:46