Default template type vs default value

This question follows the previous one .


Case 1: Default Type

The following program does not compile or report error C2995: 'T foo(void)': function template has already been defined:

#include <iostream>
#include <type_traits>

template < typename T, typename = std::enable_if_t< std::is_integral<T>::value> >
T foo() { std::cout << "integral" << std::endl; return T(); }

template < typename T, typename = std::enable_if_t< !std::is_integral<T>::value> >
T foo() { std::cout << "non-integral" << std::endl; return T(); }

int main() {
    foo<int>();
    foo<float>();
}

Each of the patterns is alternately used and ignored (SFINAE), through two instances foo. Therefore, I assume that at some point the compiler sees:

template < typename T, typename = void >
T foo() { std::cout << "integral" << std::endl; return T(); }

template < typename T, typename = void >
T foo() { std::cout << "non-integral" << std::endl; return T(); }

Both definitions are the same, and the error is somewhat understandable. Perhaps it is less clear why the compiler did not assign different names of internal functions to this point.


Case 2: default value

Now the program can be fixed, instead of using the default types, we use the default values:

template < typename T, std::enable_if_t< std::is_integral<T>::value>* = nullptr >
T foo() { std::cout << "integral" << std::endl; return T(); }

template < typename T, std::enable_if_t< !std::is_integral<T>::value>* = nullptr >
T foo() { std::cout << "non-integral" << std::endl; return T(); }

Here, following the same procedure, I get:

template < typename T, void* = nullptr >
T foo() { std::cout << "integral" << std::endl; return T(); }

template < typename T, void* = nullptr >
T foo() { std::cout << "non-integral" << std::endl; return T(); }

, , . , , , , - :

int foo_int() { std::cout << "integral" << std::endl; return int(); }

float foo_float() { std::cout << "non-integral" << std::endl; return float(); }

int main() {
    foo_int();
    foo_float();
}

, ?

?

+4
1

, , :

. ( ):

template < typename T, std::enable_if_t< std::is_integral<T>::value>*>
T foo();

template < typename T, std::enable_if_t< !std::is_integral<T>::value>*>
T foo();

void*. std::enable_if_t<std::is_integral<T>::value>* std::enable_if_t<!std::is_integral<T>::value>* . . T, .

[temp.over.link]:

, , , , (3.2), , , , , , , . , (14.6.2) , , .

, , , , , , . : , , , , . , , , ; .

.

+4

Source: https://habr.com/ru/post/1658963/


All Articles