Search code examples
c++templatesvector

Extract type from a template, but dont do it for every types


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


Solution

  • 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`
    

    Demo