dimanche 28 janvier 2018

Deduce/erase type of template template argument

When using template template arguments how can I have the template type of the template template deduced or erased?

Consider the following SSCCE:

#include <cstdint>
#include <cstddef>
#include <iostream>
using namespace std;

template<int i>
struct Value { };

template<int i>
struct BadValue { };

template<typename... G>
struct Print;

template<template<int> class ValueType, int... Is>
struct Print< ValueType<Is>... > {
    static void print() {
        const int is[] = { Is... };
        for (int i: is)
            cout << i;
        cout << endl;
    }

};

using V1 = Value<1>;
using V2 = Value<2>;
using V3 = Value<3>;
using BV = BadValue<1>;

int main() {
    Print<V2, V1, V2, V3>::print();
    Print<V2, V1, V2, VB>::print(); // <-- Error
}

Deducing the template<int> class ValueType argument of the Print class to a template class like the Value and BadValue classes enforces that all the template arguments in the parameter pack to the Print class are specializations of the same ValueType template class. That is, the second line in the main() function causes a compile-time error as the ValueType argument cannot be deduced to match both the Value and BadValue classes.

The above implementation, however, still has the int type fixed for the inner template argument of the ValueType template template argument. How can I erase it and have it deduced as well?

Generally speaking, when deducing a template template argument, how can I access the inner template argument?

Aucun commentaire:

Enregistrer un commentaire