Home > Blockchain >  How to get template class template parameter?
How to get template class template parameter?

Time:02-08

I have a template class and want to know, how to get template class variable type when it is used as a template parameter of function. I tried to do the following

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
class foo
{
};

template <typename templateClass>
void f()
{
    if (is_same<typename templateClass::T, int>::value)
        cout << "int";
    else if (is_same<typename templateClass::T, double>::value)
        cout << "double";
    else
        cout << "Unknown type";
}

int main()
{
    f<foo<double>>();

    return 0;
}

This code does not compile, because no type named 'T' in 'foo<double>'. Then I changed it a little bit:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
class foo
{
public:
    using Type = T; //can't write : using T = T;
};

template <typename templateClass>
void f()
{
    if (is_same<typename templateClass::Type, int>::value)
        cout << "int";
    else if (is_same<typename templateClass::Type, double>::value)
        cout << "double";
    else
        cout << "Unknown type";
}

int main()
{
    f<foo<double>>();

    return 0;
}

Now it works fine, but I had to rename template parameter. Can I get template parameter value without renaming it with using?

CodePudding user response:

You can create traits to extract that information without changing originel types.

template <typename T>
struct template_parameter;

template <template <typename ...> class C, typename T>
struct template_parameter<C<T>>
{
    using type = T;
};

template <typename T>
using template_parameter_t = typename template_parameter<T>::type;

and then

template <typename templateClass>
void f()
{
    if constexpr (std::is_same_v<template_parameter_t<templateClass>, int>::value)
        std::cout << "int";
    else if constexpr (std::is_same_v<template_parameter_t<templateClass>, double>::value)
        std::cout << "double";
    else
        std::cout << "Unknown type";
}

CodePudding user response:

You gain access to the variable by templating the inner argument, like so:

template <class T>
void f(foo<T>)
{
    if constexpr (std::is_same_v<T, int>)
        std::cout << "int";
    else if constexpr (std::is_same_v<T, double>)
        std::cout << "double";
    else
        std::cout << "Unknown type";
}

int main()
{
    f(foo<double>());
}

Demo

How you organise the code into structs or functions is going to depend on your real-world use case.

  •  Tags:  
  • Related