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
pointers1
andcb
to caller such that the type ofcb
is inferred from the type ofs1->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);
}