Reputation: 247
I have a template class called Array
template<typename T, int dimension>
class Array<typename T, int dimension>{
//definition of the class
}
I want to write a non-member function cast such that I can cast Array into different type. For example
Array<int, 2> a;
Array<float, 2> b = cast<float>(a);
How should I write this function? I am more interested in how to declare it instead of how to implement the detailed casting. I have tried
template<template<typename T, int dimension> class Array, typename New_T, int dimension>
Array<typename New_T, int dimension> cast(Array<typename T, int dimension> a){
// detailed implementation of casting, which I do not care for this question.
}
but it cannot pass the compilation.
Upvotes: 1
Views: 117
Reputation: 66230
How should I write this function? I am more interested in how to define it instead of how to implement the detailed casting.
I suppose something like
template <typename ToT, typename FromT, int Dim>
Array<ToT, Dim> cast (Array<FromT, Dim> const & inA)
{
// ...
}
It's useful place ToT
(to-type) in first position so you can explicit it and let FromT
and Dim
deduced from the inA
value.
--- EDIT ---
The OP asks
Any insight why I have to put it [
ToT
] in the first position?
You don't necessarily have to put ToT
in first position. But this simplify your life.
The point is that FromT
and Dim
are deducible from the inA
argument; ToT
isn't deducible from arguments so you have to explicit it.
But if you want to explicit a template parameter, you necessarily have to explicit the preceding parameters. So if you put ToT
in last position, you have to call cast()
explicating all template parameters
cast<int, 2, float>(a);
If you place ToT
in first position, you have to explicit only it and leave the compiler deduce FromT
and Dim
from the argument
cast<float>(a);
Upvotes: 2
Reputation: 30694
You don't need template template parameters at all here. Simple typename
and int
parameters will do:
template <typename T, int dimension>
class Array
{
// ...
};
template <typename NewT, typename T, int dimension>
Array<NewT, dimension> cast(const Array<T, dimension>& a)
{
// ...
}
You only need template template parameters when you want to accept different types of templates. For instance, if you wanted cast
to be able to accept an Array
or a std::array
, you could use a template template parameter:
template<typename NewT, typename T, auto dimension, template<typename, auto> typename ArrayT>
ArrayT<NewT, dimension> cast(const ArrayT<T, dimension>& a)
{
// ...
}
Note in this case I also changed the type of dimension
to auto
since std::array
uses a size_t
for its dimension while your Array
uses int
.
Upvotes: 3