Home > Back-end >  match against template template type parameter
match against template template type parameter

Time:05-29

Say I would like to type-match any container with a specific member (a constraint) - but also bind type variables to both the container and the member. For example let T and U be the template type variables corresponding to class and member Someclass.member. Is this possible?

Let's simplify things by templating the container. This moves the member type into the type system as the template type parameter which allows removing the constraint. Now can I bind the type variables to both the template type and the template type parameter? For example let T and U be the template type variables corresponding to the templated container T<U>. Is this possible?

For example,

template <typename T>
struct S1 {
    T a;
    int b;
};

struct S2 {
    S1<int> a;
    S1<double> b;
};

void cb(auto*);

// Many things have been tried
template<T<U>>
template<template<typename U> typename T>
void caller(T<U>*, void (*)(U*));

template<S1<T>>
void caller(S1<T>*, void (*)(T*));

template<T>
void caller<S1<T>>(S1<T>*, void (*)(T*));

CodePudding user response:

I want to pass an S1 pointer s1 and cb to caller such that the type of cb is inferred from the type of s1->a

Like this?

#include <iostream>
#include <type_traits>

template <typename T>
struct S1 {
    T a;
    int b;
};

template <typename T>
void caller(S1<T> *, void (*)(std::type_identity_t<T> *)) {}

int main()
{
    S1<int> s1;
    caller(&s1, [](int *){});
}

Here type_identity_t is needed to stop T from being deduced from the second argument, which confuses the compiler when passing a lambda.

CodePudding user response:

The caller's template list should be

template <typename T>
struct S1 {
  T a;
  int b;
};

void cb(auto*);

template<template<typename...> typename Temp, typename U>
void caller(Temp<U>*, void (*)(U*));

int main() {
  S1<int> a;
  caller(&a, cb);

  S1<double> b;
  caller(&b, cb);
}

Demo

  • Related