c++ - difference between template parameters typename vs non typenames? -


code sample 1:

namespace detail {     enum enabler { dummy }; }  class foo { public:     template <typename t,               typename std::enable_if<!std::is_integral<t>::value,                                       detail::enabler>::type = detail::enabler::dummy>     void func(t t) {         std::cout << "other" << std::endl;     }      template <typename t,               typename std::enable_if<std::is_integral<t>::value,                                       detail::enabler>::type = detail::enabler::dummy>     void func(t t) {         std::cout << "integral" << std::endl;     } }; 

code sample 2:

namespace detail {     enum enabler { dummy }; }  class foo { public:     template <typename t,               typename t2 = typename std::enable_if<!std::is_integral<t>::value, detail::enabler>::type>     void func(t t) {         std::cout << "other" << std::endl;     }      template <typename t,               typename t2 = typename std::enable_if<std::is_integral<t>::value, detail::enabler>::type>     void func(t t) {         std::cout << "integral" << std::endl;     } }; 

i understand why sample 2 not compile. because both template functions each other (they have same template parameters t, t2).

i not understand why sample 1 compiles! see it's same problem. instead of having second template parameter typename, it's enum instead of typename time.

can explain please?

further, executed following piece of code , returned true more confusing! (makes sense it's true confusing sample 1 compiles)

std::cout     << std::boolalpha     << std::is_same<std::enable_if<std::is_integral<int>::value, int>::type,                     std::enable_if<!std::is_integral<float>::value, int>::type>::value     << std::endl; 

default arguments (whether default function arguments or default template arguments) not part of function signature. allowed define 1 function given signature.

in code sample 1, if drop names of arguments , defaults, have 2 functions are:

template <typename t, std::enable_if_t<!std::is_integral<t>::value, detail::enabler>> void func(t ) { ... }  template <typename t, std::enable_if_t<std::is_integral<t>::value, detail::enabler>> void func(t ) { ... } 

those 2 different signatures - 2nd template parameter has different types in both functions - it's valid perspective.

now, happens when call it. if t integral type, 2nd argument gets substituted in both cases:

template <typename t, ????>                    void func(t ) { ... } template <typename t, detail::enabler = dummy> void func(t ) { ... } 

in first function, expression typename std::enable_if<false, detail::enabler>::type ill-formed. there no type typedef on type. typically, writing ill-formed code hard compiler error. but, rule called sfinae (substitution failure not error), ill-formed code arising in immediate context of template substitution not error - causes function/class template specialization removed consideration set. end 1 valid one:

template <typename t, detail::enabler = dummy> void func(t ) { ... } 

which gets called.


however, in code sample 2, have these 2 functions:

template <typename t, typename> void func(t ) { ... }  template <typename t, typename> void func(t ) { ... } 

those same! we're defining same function twice - not allowed, hence error. error same reason that:

int foo(int x = 1) { return x; } int foo(int x = 2) { return x; } 

is error.


this why xeo used (unconstructible) enum enable if begin - makes easier write disjoint function template specializations since can enum can't types.

note same int:

template <class t, std::enable_if_t<std::is_integral<t>::value, int> = 0> void func(t ) { ... } 

but allow evil user provide value argument (it wouldn't matter in particular context in others). detail::enabler, no such value can provided.


Comments

Popular posts from this blog

javascript - Laravel datatable invalid JSON response -

java - Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; -

sql server 2008 - My Sql Code Get An Error Of Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '8:45 AM' to data type int -