Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a function template that returns either a reference or a value?

I'd like to write a function template that returns either a reference or a value depending on some compile time expression. What I've tried so far is something like this:

template<typename T>
auto&& Func()
{
  if constexpr (some_compile_time_expression)
  {
    return GetReferenceFromSomewhere();
  }
  else
  {
    return GetValueFromSomewhere();
  }
}

This works fine for all types of references but doesn't work for values. For example, if GetValueFromSomewhere returns a Foo, then the compiler deduces the return type of Func as Foo&& and warns that I'm returning the address of a temporary.

Is there any way to make this work, or am I forced to tease the two branches apart somehow (through function overloads or some such)?

like image 537
Peter Ruderman Avatar asked Jun 07 '18 03:06

Peter Ruderman


People also ask

Can a function return a value by reference?

Functions in C++ can return a reference as it's returns a pointer. When function returns a reference it means it returns a implicit pointer.

What is a function template?

Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes. The following function template swaps two items: C++ Copy.

How do you write a function template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

What is a template template parameter in C++?

In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.


1 Answers

Use decltype(auto) for the return type placeholder, it will preserve the exact value category of the function you're calling in the return statement

template<typename T>
decltype(auto) Func()
{
  if constexpr (some_compile_time_expression_dependent_on_T)
  {
    return GetReferenceFromSomewhere();
  }
  else
  {
    return GetValueFromSomewhere();
  }
}

Live demo

like image 93
Praetorian Avatar answered Oct 26 '22 22:10

Praetorian