I already know that you can enable (or not) a class's method using std::enable_if
for exemple:
template<size_t D, size_t E>
class Field
{
...
size_t offset(const std::array<float,D>& p) const
{
...
}
template<typename TT = size_t>
typename std::enable_if<D!=E, TT>::type
offset(const std::array<float,E>& p) const
{
return offset(_projection(p));
}
...
};
This helps not being able to call function that are invalid in a specific case as well as removing overloading errors ... which, to me, is very nice !
I'd like to go further and make some of my class's members being present only if the are needed. That way I would get an error if I try to use an objected which would have otherwise not been initiated
I tried to do
template<size_t D, size_t E>
class Field
{
...
template<typename TT = projectionFunc>
typename std::enable_if<D!=E, TT>::type _projection;
}
But the compiler tells me :
erreur: data member ‘_projection’ cannot be a member template
Is there any way to achieve what I want ?
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
Member functions of class templates (C++ only) You may define a template member function outside of its class template definition. The overloaded addition operator has been defined outside of class X . The statement a + 'z' is equivalent to a. operator+('z') .
Templates are the foundation of generic programming, which involves writing code in a way that is independent of any particular type. A template is a blueprint or formula for creating a generic class or a function.
A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.
Hold the data members in a separate class that you can then specialize as needed.
template<size_t D, size_t E>
class Field {
template<size_t, size_t> struct Field_Members {
int _projection;
};
template<size_t V> struct Field_Members<V, V> { };
Field_Members<D, E> m;
};
and then use m._projection
etc.
Field_Members
doesn't have to be a nested class template; you can move it outside if desired. It is also possible to have Field
inherit from it, but then it'd be a dependent base, and you'd have to write this->_projection
, so it doesn't save much typing.
AFAIK, this is not possible with a simple SFINAE inside the class template. You can, of course, have the type of the member dependent on a compile-time condition, i.e. via std::conditional
, but not eliminate the member entirely.
What you can do, of course, is use another class template, such as
template<bool Condition, typename T> struct Has { T value; };
template<typename T> struct Has<false,T> {};
and declare a member (or base) of this type and access the object via Has<>::value
:
typename<bool Condition>
class foo
{
Has<Condition, double> x; // use x.value (only if Condition==true)
};
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