Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template class specialization enable_if and default values

Tags:

c++

c++11

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;
}
like image 834
rmawatson Avatar asked Jun 06 '18 13:06

rmawatson


People also ask

What is Enable_if in C++?

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.

What is a template specialization in C++?

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.

What is template specialization used for?

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.

What is the difference between class and Typename in template?

There is no difference between using <typename T> OR <class T> ; i.e. it is a convention used by C++ programmers.


2 Answers

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

like image 139
UmNyobe Avatar answered Oct 07 '22 00:10

UmNyobe


test<int> v; is test<int, void> v; (thanks to default type).

test<int, int> v; would select your last specialization.

like image 43
Jarod42 Avatar answered Oct 07 '22 01:10

Jarod42