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>
.
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;
}
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.
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 thentest<T,T>
.
You wrote test<int>
, which means that you didn't provide any template argument for the second parameter. Because it has a default parameter, it is chosen, so you actually have test<int, void>
.
Now, according to the text linked above, the template parameters are matched to a specialization.
In the first case, the specialization is test<int, void>
after evaluation, and so it is an exact match and chosen.
In the second case, the specialization is test<int, int>
after evaluation, which is not an exact match and so the primary template is chosen instead of that specialization.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.