如何编写返回引用或值的函数模​​板?

时间:2018-06-07 03:32:09

标签: c++ templates c++17

我想编写一个函数模板,根据某些编译时表达式返回引用或值。到目前为止我所尝试的是这样的:

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

这适用于所有类型的引用,但不适用于值。例如,如果GetValueFromSomewhere返回Foo,则编译器会将Func的返回类型推断为Foo&&,并警告我返回临时地址

有没有办法使这项工作,或者我被迫以某种方式分开两个分支(通过函数重载或某些)?

2 个答案:

答案 0 :(得分:16)

使用decltype(auto)作为返回类型占位符,它将保留您在return语句中调用的函数的确切值类别

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

Live demo

答案 1 :(得分:3)

Pretorian的答案是完美的,但您可能还想了解std::conditional,它具有更广泛的用途。例如,考虑类型data_的{​​{1}}成员变量和成员函数,它根据某些编译时条件通过引用或值返回int

data_

使用template <bool COND> std::conditional_t<COND, int&, int> data() { return data_; } 无法实现这一点。您还可以使用相同的技术通过reference / value将参数传递给函数:

decltype(auto)

或者,您可以在复制/移动构造函数之间切换:

template <bool COND>
void f(std::conditional_t<COND, int&, int> param);

等等...