Pet*_*man 11 c++ templates c++17
我想编写一个函数模板,它根据一些编译时表达式返回一个引用或一个值.到目前为止我尝试的是这样的:
template<typename T>
auto&& Func()
{
if constexpr (some_compile_time_expression)
{
return GetReferenceFromSomewhere();
}
else
{
return GetValueFromSomewhere();
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于所有类型的引用,但不适用于值.例如,如果GetValueFromSomewhere返回a Foo,那么编译器会推断Funcas 的返回类型,Foo&&并警告我正在返回临时的地址.
有没有办法让这个工作,或者我被迫以某种方式分开两个分支(通过功能重载或一些这样的)?
Pra*_*ian 16
使用decltype(auto)返回类型占位符,它会保留你在调用该函数的精确值类return声明
template<typename T>
decltype(auto) Func()
{
if constexpr (some_compile_time_expression_dependent_on_T)
{
return GetReferenceFromSomewhere();
}
else
{
return GetValueFromSomewhere();
}
}
Run Code Online (Sandbox Code Playgroud)
Pretorian 的答案很完美,但您可能还想了解std::conditional,它有更广泛的用途。例如,考虑一个data_类型的成员变量int和一个成员函数,它data_根据某些编译时条件通过引用或值返回:
template <bool COND>
std::conditional_t<COND, int&, int> data() { return data_; }
Run Code Online (Sandbox Code Playgroud)
这是无法实现的decltype(auto)。您还可以使用相同的技术通过引用/值将参数传递给函数:
template <bool COND>
void f(std::conditional_t<COND, int&, int> param);
Run Code Online (Sandbox Code Playgroud)
或者,您可以在复制/移动构造函数之间切换:
class X {
X(std::conditional_t<some_cond, const X&, X&&>) = default;
X(std::conditional_t<some_cond, X&&, const X&>) = delete;
...
};
Run Code Online (Sandbox Code Playgroud)
ETC...