Suppose I had a templated object in C Test<T>
and I wanted to find out what the T value is so that when I pass Test<T>
as a template argument to TestWrapper<Test<T>>
, I can declare a variable called T extradata
in the object TestWrapper
that is the same as Test
's T type.
How can I achieve this by only modifying TestWrapper (i.e. making no changes to Test struct) ? Additionally is it possible to modify it so that it will extract from any object that takes 1 template parameter e.g. foo<T>
, bar<T>
, rather then just Test<T>
>?
Thanks in advance.
template<typename T>
struct Test {
T value;
};
//template -> extract first type parameter from any object as T
struct TestWrapper {
T extradata;
};
int main() {
TestWrapper<Test<int>> temp;
temp.extradata = 123; // temp.extradata is a int, deduced from Test<int>
}
CodePudding user response:
You can use partial template specialization to do that.
template<typename T>
struct Test {
T value;
};
template <typename T>
struct TestWrapper;
template <template <typename> typename Outer, typename T>
struct TestWrapper<Outer<T>> {
T extradata;
};
int main() {
TestWrapper<Test<int>> temp;
temp.extradata = 123; // temp.extradata is a int, deduced from Test<int>
}
In this example we have not defined any default definition for TestWrapper
, so it will fail to compile if you give something that does not match the specialization.
CodePudding user response:
You can
// primary template
template <typename T>
struct TestWrapper {
T extradata; // declare extradata with type T
// how to declare it depends on your intent
};
// partial specialization
template <template <typename...> class C, typename T, typename... Args>
struct TestWrapper<C<T, Args...>> {
T extradata; // T is the 1st template parameter of C here
};
CodePudding user response:
You can create a helper class to extract the first parameter of the instantiated template, for example:
template<class>
struct Extract;
template<template<class...> class V, class First, class... Rest>
struct Extract<V<First, Rest...>> {
using type = First;
};
template<class T>
struct TestWrapper {
typename Extract<T>::type extradata;
};