I have this code
template <typename T>
struct TestWrapper;
template <template <typename> typename Outer, typename T>
struct TestWrapper<Outer<T>> {
T extradata;
vector<T>make_vector() {
return vector<T>{};
}
T make_var() {
return T();
}
};
It works quite good for vector<int>
, but not for int
obviously, C++ throw compilation error "TestWrapper has incomplete type".
I want to return T
if T
can't be parsed by Outer<T>
and Outer<T>
instead if it is possible. How can I do this?
Expected results:
1) TestWrapper<vector<int>> tmp; // T is int
2) TestWrapper<int> tmp; // T is int
3) TestWrapper<vector<vector<int>>> tmp; // T is vector<int>
Right now my code works for 1 and 3 case, but for 2 case the error is "error: aggregate 'TestWrapper tmp' has incomplete type and cannot be defined TestWrappertmp;"
There are only std::vectors, num types like int, long long, unsigned int, double And maybe type std::string
I want to return T if T can't be parsed by Outer and Outer instead if it is possible.
I think you mean that, if T
is of the form Outer<U>
, then you want to use U
, but otherwise you want to use T
directly. What this quote of yours says is equivalent to "I want to return T
".
Here is how you can do what I think you mean:
template<typename T>
struct MaybeInnerType {
using type = T;
};
template<template<typename...> class Outer, typename U>
struct MaybeInnerType<Outer<U>> {
using type = U;
};
template<typename T>
using MaybeInnerTypeT = typename MaybeInnerType<T>::type; // typename needed in C++17, not in C++20
// usage: `MaybeInnerTypeT<std::vector<int>>` is `int`