I have a variadic template class with set function, that fills interal array:
template <size_t Dim>
class Vector
{
public:
void SetValueTemplate(size_t index)
{
return;
}
template <typename X0, typename ...Xn>
void SetValueTemplate(size_t index, X0 x0, Xn... xn)
{
val[index] = x0;
SetCenterValueTemplate(index + 1, xn...);
}
template <typename ...X0>
void SetValue(X0... t0)
{
SetValueTemplate(0, t0...);
}
private:
double val[Dim];
};
Problem is, that I can call this
Vector<3> v;
v.SetValue(0, 1, 2, 4, 5);
and it compiles correctly. Can I limit this to not compile? I can use static_assert, but is it possible without it?
Yes, this is possible, without static_assert. For example, let's assume we want our vector class to only be assignable with the name number of arguments as the dimension of the vector, you can use:
template<std::size_t Dim>
struct vector {
template <typename X0, typename ...Xn>
typename std::enable_if<sizeof...(Xn) + 1 == Dim, void>::type
assign(X0 x0, Xn... xn) {}
};
This just uses std::enable_if in combination with sizeof... to enable or disable the specific assign function.
So the following will compile:
vector<3> x;
x.assign(1, 2, 3);
Live demo
but this won't:
vector<3> x;
x.assign(1, 2, 3, 4);
Live demo
with (for Clang):
main.cpp:14:7: error: no matching member function for call to 'assign'
x.assign(1, 2, 3, 4);
~~^~~~~~
and neither will this:
vector<3> x;
x.assign(1, 2);
Live demo
with a similar error message.
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