Given the following
template <typename T, typename Enable=void>
struct test{};
template <typename T,
typename std::enable_if< some_trait<T>::value >::type >
struct test{};
assuming some_trait<T>::value
is true
, enable_if<T>::type
is void
, and the specialization is selected.
However, my query is related to the selection when the follow is the case.
template <typename T,
typename std::enable_if_t< some_trait<T>::value,T>::type >
struct test{};
When a second non void template parameter for enable_if
is provided for ::type
, the unspecialized template
is selected, even when some_trait<T>::value
is true
, as ::type
is T
instead of void
, and so doesn't
match the default value in the primary template.
My question is where in the standard is the ordering described for which template is chosen, and why is
the instanciation test<T,void>
considered as a better match then test<T,T>
.
https://ideone.com/7v4TTS
full sample :
#include <iostream>
#include <type_traits>
template <typename T,typename Enable=void>
struct test
{
const char* value = "Primary";
};
#if 1// toggle this
template <typename T>
struct test<T,typename std::enable_if< std::is_same<T,T>::value >::type >
{
const char* value = "Specialization";
};
#else
template <typename T>
struct test<T,typename std::enable_if< std::is_same<T,T>::value,T >::type>
{ /// ^
const char* value = "Specialization";
};
#endif
int main() {
test<int> v;
std::cout << v.value << std::endl;
return 0;
}
The enable_if family of templates is a set of tools to allow a function template or a class template specialization to include or exclude itself from a set of matching functions or specializations based on properties of its template arguments.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
It is possible in C++ to get a special behavior for a particular data type. This is called template specialization. Template allows us to define generic classes and generic functions and thus provide support for generic programming.
There is no difference between using <typename T> OR <class T> ; i.e. it is a convention used by C++ programmers.
In the first case you have the type
std::enable_if< true, void >
In the second case you have the type
std::enable_if< true, int >
std::enable_if< true, int >::type
is int
. It doesnt qualify a as type for typename Enable
, which was requested to be void
test<int> v;
is test<int, void> v;
(thanks to default type).
test<int, int> v;
would select your last specialization.
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