C++ detect if type has template parameter
Asked Answered
C

1

6

I would like to unify an interface to work with both templated and non-templated types. Is there a way to determine whether a type, such as a class or a function pointer is depends on a template parameter?

For example:

struct foo {};
template<typename T>  struct bar {};

// This works if the template parameter is provided
template<typename> struct is_templated : false_type {};
template<template<typename...> class Obj, typename...Args>
struct is_templated<Obj<Args...>> : true_type {};
template<typename T> constexpr auto is_templated_v = is_templated<T>::value;

In this case, is_template_v<foo> is false and is_template_v<bar<int>> is true, but I can't just deduce anything with is_template_v<bar>. Alternatively, if I define

template<template<typename...> class> 
struct temp_check : true_type {};

Then temp_check<bar> is perfectly valid, but I don't know how I would analogously check foo. What is needed is something like this if it were valid C++

template<template<> class A> struct temp_check<A> : false_type {};

Is there some mechanism that could check both?

Cida answered 7/2, 2019 at 17:42 Comment(1)
bar<int> is a specific type. bar on the other hand is a template. You can check for both but you need two different specializations of is_template to do so.Toronto
S
7

I'd use the power of overload sets:

#include <iostream>
#include <type_traits>

struct foo {};
template<typename T>  struct bar {};

template<template<class ...> class T, class... TArgs>
constexpr bool is_template() { return true; }

template<class T>
constexpr bool is_template() { return false; }

int main()
{
    std::cout << is_template<foo>() << '\n'; // 0
    std::cout << is_template<bar>() << '\n'; // 1
}

Let to the user: use the template function to provide a trait ;)

Stepsister answered 7/2, 2019 at 17:57 Comment(2)
This is a nice solution if the types are classes, but is this approach or similar possible if foo and bar were functions?Cida
@GregvonWinckel not quite. I would suggest using a class with a call operator in it since manupilating types is much easier than manipulating function pointresBoltonia

© 2022 - 2024 — McMap. All rights reserved.