Vince
Vince

Reputation: 4401

c++ r-value reference applied to function pointer

#include <iostream>
#include <utility>

template<typename T>
void f1(T&& t) // && 
{

  if constexpr (std::is_function_v<typename std::remove_pointer_t<T>>)
                 std::cout << "function" << std::endl;
  else
    std::cout << "not a function" << std::endl;
}


template<typename T>
void f2(T& t) // & 
{

  if constexpr (std::is_function_v<typename std::remove_pointer_t<T>>)
                 std::cout << "function" << std::endl;
  else
    std::cout << "not a function" << std::endl;
}


void print(){}


int main()
{
    f1(print);
    f2(print);

    return 0;
}

According to f1, print is not a function.

According to f2, print is a function.

Understanding why this is so would help understanding the && operator

Upvotes: 1

Views: 1078

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310960

In the both cases a function is passed by reference. And the both functions deals with lvalue reference to the function print.

Use

std::is_function_v<std::remove_reference_t<T>>

instead of

std::is_function_v<typename std::remove_pointer_t<T>>

You can also insert a statement like this in the both functions

std::cout << std::is_lvalue_reference_v<decltype( t )> << '\n';

to be sure that the functions deal with the lvalue reference to rpint.

Take into account that you need to include the header <type_traits>.

If you want that the functions would deal with function pointers then you need to use a call like this

f1(&print);

In this case the second function should be declared like

template<typename T>
void f2( const T& t);

Otherwise you may not bind a non-constant reference to rvalue.

Or call the function f2 like if you do not want to use the qualifier const.

auto p = print;

f2(p);

Upvotes: 1

Related Questions