我想编写一个函数模板,根据某些编译时表达式返回引用或值。到目前为止我所尝试的是这样的:
template<typename T>
auto&& Func()
{
if constexpr (some_compile_time_expression)
{
return GetReferenceFromSomewhere();
}
else
{
return GetValueFromSomewhere();
}
}
这适用于所有类型的引用,但不适用于值。例如,如果GetValueFromSomewhere
返回Foo
,则编译器会将Func
的返回类型推断为Foo&&
,并警告我返回临时地址
有没有办法使这项工作,或者我被迫以某种方式分开两个分支(通过函数重载或某些)?
答案 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();
}
}
答案 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);
等等...