Different behavior when choosing template overload when using rvalue links

The following code:

#include <stdio.h>

class Base {};

template< typename... T >
void test1( T const & ... )
{
  printf( "test1( args ) called\n" );
}

template< typename... T >
void test1( Base const &, T const & ... )
{
  printf( "test1( base, args ) called\n" );
}

template< typename... T >
void test2( T && ... )
{
  printf( "test2( args ) called\n" );
}


template< typename... T >
void test2( Base const &, T && ... )
{
  printf( "test2( base, args ) called\n" );
}

int main()
{
  test1( 1, 2, 3 );
  test1( Base(), 1, 2, 3 );

  test2( 1, 2, 3 );
  test2( Base(), 1, 2, 3 );
}

outputs:

test1( args ) called
test1( base, args ) called
test2( args ) called
test2( args ) called

The compiler named a more specific version test1when it was sent Base. However, this was not done in the case test2- the overload that accepts Basewas never called. Why test1does the compiler honor specifics with , but not with test2?

+4
source share
2 answers

Overloading test1(Base const&, T...)is preferred vs test1(T const...)because it is more specialized, the compiler does not need to draw type inference for the first parameter in the first case.

test2: Base() rvalue, T&& Base const&. T&& , T Base, Base&& Base const&.

, (, , ) , , . , , "" (. 26 ++" ).

+3

http://en.cppreference.com/w/cpp/language/template_argument_deduction http://en.cppreference.com/w/cpp/language/overload_resolution

Base() rvalue, :

test2( Base(), 1, 2, 3 );

rvalue Base ( ):

 void test2( Base const &, T && ... )

, :

 void test2( T && ... )

.

, , , , -const rvalue Base ( " " ):

 void test2( Base &&, T && ... )

const lvalue Base :

 const Base b;
 test2( b, 1, 2, 3 );
+1

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


All Articles