Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get template parameter of a template template parameter?

Assume std::vector didnt have a value_type. Is is possible to write a template to deduce the value_type? Or more general, given a T<X>, how can I deduce X?

A very naive..

template <template <typename X> T>
void test(T<X> t) { 
     X x;
}

will probably make anybody who knows a bit about templates laugh at my foolish attempt and when instantiated like this:

int main() {
    std::vector<int> x;
    test(x);
}

create the following errors:

error: expected ‘class’ before ‘T’
 template < template<typename X> T>
                                 ^
error: ‘X’ was not declared in this scope
 void test(T<X> u) {
             ^
error: template argument 1 is invalid
 void test(T<X> u) {
              ^
In function ‘void test(int)’:
error: ‘X’ was not declared in this scope
   X x;
   ^
error: expected ‘;’ before ‘x’
   X x;
     ^
In function ‘int main()’:
error: no matching function for call to ‘test(std::vector<int>&)’
   test(x);
         ^
note: candidate is:
note: template<template<class X> class T> void test(int)
 void test(T<X> u) {
      ^
note:   template argument deduction/substitution failed:
note:   cannot convert ‘x’ (type ‘std::vector<int>’) to type ‘int’

EDIT: the first one is easy to fix, but fixing it wont affect the others...

PS: I think I have a small misunderstanding, as std::vector<int> isnt a template, but a concrete type. However, still I would like to know if there is a way to get the int from a someTemplate<int> with some template magic.

like image 296
463035818_is_not_a_number Avatar asked Jul 25 '17 13:07

463035818_is_not_a_number


People also ask

Can template parameter be a template?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Which is correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.

What is a template argument in C++?

In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Why do we use :: template template parameter?

8. Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

What is a template argument for a template parameter?

A template argument for a type template parameter must be a type-id, which may name an incomplete type: A template argument for a template template parameter must be an id-expression which names a class template or a template alias. When the argument is a class template, only the primary template is considered when matching the parameter.

How do I parameterize a template?

Every template is parameterized by one or more template parameters, indicated in the parameter-list of the template declaration syntax: template < parameter-list > declaration Each parameter in parameter-list may be: a non-type template parameter;

What is a non-type template parameter?

A non-type template parameter must have a structural type, which is one of the following types (optionally cv-qualified, the qualifiers are ignored): the types of all base classes and non-static data members are structural types or (possibly multi-dimensional) array thereof.

What is a default template parameter in C++?

If the default is specified for a template parameter of a primary class template , primary variable template, (since C++14)or alias template, each subsequent template parameter must have a default argument, except the very last one may be a template parameter pack.


1 Answers

You can create a traits to extract those parameter:

template <typename T> struct first_param;

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

For pre C++11, you have to handle number of parameters until acceptable values:

template <typename T> struct first_param;

template <template <typename> class C, typename T>
struct first_param<C<T>>
{
    typedef T type;
};

template <template <typename, typename> class C, typename T, typename T2>
struct first_param<C<T, T2>>
{
    typedef T type;
};

template <template <typename, typename, typename> class C,
          typename T, typename T2, typename T3>
struct first_param<C<T, T2, T3>>
{
    typedef T type;
};

// ...
like image 88
Jarod42 Avatar answered Sep 28 '22 11:09

Jarod42