Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot substitute template argument for template template parameter

I have a templated struct like this:

template<int Min, int Max>
struct TInt
{
    int Get() const { return StoredVal; }
    TInt& operator=(int Val) { StoredVal = FMath::Clamp(Val, Min, Max); return *this; }
    bool WithinRange(int Val) const { return Min <= Val && Val <= Max; }

private:
    int StoredVal = Min;
};

And after reading this proposal tried to create these templates to check if a type is a template specialization of TInt:

template<class T, template<class...> class Primary>
struct is_specialization_of : std::false_type {};

template<template<class...> class Primary, class... Args>
struct is_specialization_of<Primary<Args...>, Primary> : std::true_type {};

template<class T, template<class...> class Primary>
inline constexpr bool is_specialization_of_v = is_specialization_of<T, Primary>::value;

This is how I try to use it:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

template<typename T>
struct IsValidType { static constexpr bool Value = is_specialization_of<T, TInt>; };

But I keep getting this error: "Cannot substitute template argument TInt for template template parameter Primary". I have checked and tried other answers to similar questions here on SO, but nothing really seems to work for me.

I don’t really care about the general case (variadic template), just two template parameters which would also increase my learning if I could do exactly that.

What do I need to do to make this work?

>Solution :

The problem is:

template<class T, template<class...> class Primary>
struct is_specialization_of : std::false_type {};

is_specialization_of takes something of the form template <class...> class Primary. A class template that accepts some number of type template parameters. But TInt doesn’t accept type template parameters, it accepts non-type template parameters (specifically two ints). There’s no way in C++ today to write is_specialization_of properly.


But if you just want to write a specific trait to check if something is a TInt, that’s much more straightforward with a variable template:

template <class T>
inline constexpr bool is_tint = false;

template <int Min, int Max>
inline constexpr bool is_tint<TInt<Min, Max>> = true;

or shoved onto "one line" (ish) with a requires expression:

template <class T>
concept is_tint = requires (T const& t){
    []<int Min, int Max>(TInt<Min, Max> const&){}(t);
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading