Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get decltype of template argument

I often want to get the decltype of a class template argument in order to use it further, like in a loop which I have stripped and simplified to show my problem:

template <typename T>
class Foo {
public:
    T type; //This is my hack to get decltype of T
};

template <typename T>
class Bar {
public:

};

int main() {
    for(auto& foo : fs) {
        //Is there some way to get the decltype of the template without having to refer to some arbitrary T member of Foo?
        auto bar = someFunction<decltype(foo.type)>();
    }
}

Is there a way to get the decltype of the template argument without doing this hack? If not, what is the best workaround to get the decltype of such a value?

like image 613
Gerard Avatar asked Dec 09 '14 15:12

Gerard


People also ask

What does decltype return?

The decltype type specifier yields the type of a specified expression. The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a function template whose return type depends on the types of its template arguments.

What is template argument deduction in C++?

Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.

What is the difference between auto and decltype in C++?

'auto' lets you declare a variable with a particular type whereas decltype lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression.

Is decltype runtime or compile time?

decltype is a compile time evaluation (like sizeof ), and so can only use the static type.


1 Answers

You may create a type_traits:

template <typename C>
struct get_template_type;

template <template <typename > class C, typename T>
struct get_template_type<C<T>>
{
    using type = T;
};

and then you use it (assuming C = Foo<T>, you will have T)

typename get_template_type<C>::type

Live example

EDIT: For classes with multiple template parameter, to retrieve the first one:

template <template <typename > class C, typename T, typename ... Ts>
struct get_template_type<C<T, Ts...>>
{
    using type = T;
};
like image 117
Jarod42 Avatar answered Sep 28 '22 14:09

Jarod42