C ++ templated function overload rules

When overloading a template function, how the compiler should choose which version of the function to call, if it has the ability:

  • Call the template version of the function (for example, func<T>(foo)).
  • Call an overloaded version of the function, which itself is not a template, but where the type of the function passed to the function is inherited from the type specified in the overloaded function template.

Consider the following C ++ code:

#include <stdio.h>

struct Parent {}; 
struct Child : public Parent {}; 

template <typename T>
void func(T) {
  printf("func(T)\n");
}

void func(Parent) {
  printf("func(Parent)\n");
}

int main() {
  func(1);
  func(Parent());
  func(Child());
}

Compiled using gcc or clang, these outputs:

func(T)
func(Parent)
func(T)

The first two lines are expected and make sense. However, in a call, func(Child())he could just as easily call func(Parent)(which seems to be something like what he should do).

So I have two main questions:

  • , , ? / - , .
  • func(Parent) Child?

, , , , .

+4
2

:

  • (.. ).
  • :

    . ( " " )
     .
     .

. :

func(1);

(2) , func<int>. func(Parent ) , Parent int, .

func(Parent());

: func<Parent> func(Parent ). , . , 3b: , func(Parent ).

func(Child());

: func<Child> func(Parent ). Child, , ( ). Parent, . (.. ), . func(Parent ) - , . func<Child> - .

func(Parent) Child?

Child Parent :

Child c;
func(static_cast<Parent>(c));

, Child, 3- ( 3- ):

void func(Child );

, - :

template <typename T,
          typename = std::enable_if_t<
              !std::is_convertible<T*, Parent*>::value
          >>
void func(T );

( SFINAE) func<Child> , func(Parent ).

+3

-, , . C9 STL, .

. func(Parent), . , " ".

- SFINAE, T, Parent, . ++ 17 - .

. : Core ++, 2 n -

. : Core ++, 3 n -

+1

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


All Articles