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

Is it possible to write a C++ template function whose template arg works if-and-only-if it is template?

I’m trying to write a little template function that returns sequential integer id’s for templates passed to it. The following works for many templates, but not for templates that take non-type arguments (like std::array). Is there any way to make this work more generally? If not, what is my best alternative? (I’m tempted to just trust the caller to only pass template template args, and force them to include some kind of pointless default template args so it’s a normal type T: ttypeid<vector<void>>(), ttypeid<array<void, 0>>(), etc.)

#include <atomic>
#include <vector>
#include <map>
#include <array>
#include <iostream>

using namespace std;

inline unsigned gen_id() {
    static atomic<unsigned> id = 0;
    return ++id;
}

template <template<typename ...> typename T>
inline unsigned ttypeid() {
    static unsigned id = gen_id();h
    return id;
}

int main() {
    cout << ttypeid<vector>() << endl;
    cout << ttypeid<map>()    << endl;

    // cout << ttypeid<array>()  << endl;
    //
    // error: no matching function for call to
    //     ‘ttypeid<template<class _Tp, long unsigned int _Nm> struct std::array>()’

    return 0;
}

>Solution :

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

Unfortunately type and non-type template (variadic) arguments do not mix well.

For std::array you can add this:

template <template<typename, auto,typename...> typename T>
inline unsigned ttypeid() {
    static unsigned id = gen_id();
    return id;
}

Live Demo

Though, if you want to handle another template, lets say T<Type,int,Type,int,Type> you need to write another overload. The good thing is that non-type template arguments are not that abundant. In your own templates you can avoid them by wrapping values in a type instead of using the bare value (cf. eg. std::integral_constant).

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