Was not exactly sure how to phrase this question or what to search on so if this is the same as another question please close and redirect to the appropriate question.
Suppose
template<typename Type, int Size> class vector
{
Type data[Size];
}
Is it possible to replace a constructor which takes Size number of arguments in template specializations like this
template<typename Type> class vector3<Type,3>
{
Type data[3];
public:
vector3( Type, Type, Type );
}
with something in the non-specialized template class? Like a "varargs constructor" that produces a constructor with Size number of arguments of type Type?
A solution involving C++0x features is fine.
In C++0x you have template typedef finally available!
Disclaimer: nothing has been compiled...
From Wikipedia's article:
template< typename second>
using TypedefName = SomeType<OtherType, second, 5>;
which in your case would yield
template <class Type>
using vector3 = vector<Type, 3>;
I can't tell you how much I craved for this ;)
However it doesn't solve the parameters issue. As mentioned, you could try and use variadic templates here, however I am unsure as to their application in this case. The normal use is with recursive methods and you would need to throw a static_assert in the midst.
Edited to take the comments into account.
template <class Type, size_t Size>
class vector
{
public:
template <class... Args>
vector(Args... args): data({args...})
{
// Necessary only if you wish to ensure that the exact number of args
// is passed, otherwise there could be less than requested
BOOST_MPL_ASSERT_RELATION(sizeof...(Args), ==, Size);
}
private:
T data[Size];
};
Another possibility that is already available is to combine Preprocessor generation with boost::enable_if.
template <class Type, size_t Size>
class vector
{
public:
vector(Type a0, typename boost::enable_if_c< Size == 1 >::type* = 0);
vector(Type a0, Type a1, typename boost::enable_if_c< Size == 2 >::type* = 0);
// ...
};
Using Boost.Preprocessor for the generation makes this easier.
BOOST_PP_REPEAT(MAX_COUNT, CONSTRUCTOR_MACRO, ~);
// where MAX_COUNT is defined to the maximum size you wish
// and CONSTRUCTOR_MACRO actually generates the constructor
#define CONSTRUCTOR_MACRO(z, n, data) \
vector( \
BOOST_PP_ENUM_PARAMS(n, Type a), \
typename boost::enable_if_c< Size == n >::type* = 0 \
);
The implementation of the constructor is left as an exercise for the reader. It's another call to BOOST_PP_REPEAT.
As you can see, it soon gets ugly, so you'll be better off if you can use the variadic template version.
There's a further solution to your problem: Using variadic template parameters in the initializer list
template<typename T, unsigned int N>
struct vector {
T data[N];
template<typename... Args>
vector(Args... args) : data({args...}) { }
};
However the number of arguments only needs to be less or equal than N and their types only needs to be convertible to T.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With