To accept also unsigned int
and other types that are convertible to int
, and if you can accept an upper limit (63, in the following example) to the number of integer argument, I propose to follow an example from W.F..
So you can develop a typer
template <typename T, std::size_t>
using typer = T;
and a recursive struct proOp
template <typename T, std::size_t N = 64U,
typename = std::make_index_sequence<N>>
struct proOp;
template <typename T, std::size_t N, std::size_t... Is>
struct proOp<T, N, std::index_sequence<Is...>> : public proOp<T, N-1U>
{
using proOp<T, N-1U>::operator();
void operator() (typer<T, Is>... ts)
{ }
};
template <typename T>
struct proOp<T, 0U, std::index_sequence<>>
{
void operator() ()
{ }
};
Inheriting from proOp<int>
, Tensor
become
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
The following is a full working example
#include <utility>
template <typename T, std::size_t>
using typer = T;
template <typename T, std::size_t N = 64U,
typename = std::make_index_sequence<N>>
struct proOp;
template <typename T, std::size_t N, std::size_t... Is>
struct proOp<T, N, std::index_sequence<Is...>> : public proOp<T, N-1U>
{
using proOp<T, N-1U>::operator();
void operator() (typer<T, Is>... ts)
{ }
};
template <typename T>
struct proOp<T, 0U, std::index_sequence<>>
{
void operator() ()
{ }
};
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}