gpt4 book ai didi

C++ 模板函数中的左值和右值

转载 作者:太空狗 更新时间:2023-10-29 19:47:40 26 4
gpt4 key购买 nike

我从 http://www.cplusplus.com/reference/utility/forward 中抽取样本:

// forward example
#include <utility> // std::forward
#include <iostream> // std::cout

// function with lvalue and rvalue reference overloads:
void overloaded (const int& x) {std::cout << "[lvalue]";}
void overloaded (int&& x) {std::cout << "[rvalue]";}

// function template taking rvalue reference to deduced type:
template <class T> void fn (T&& x) {
overloaded (x); // always an lvalue
overloaded (std::forward<T>(x)); // rvalue if argument is rvalue
}

int main () {
int a;

std::cout << "calling fn with lvalue: ";
fn (a);
std::cout << '\n';

std::cout << "calling fn with rvalue: ";
fn (0);
std::cout << '\n';

return 0;
}

打印

calling fn with lvalue: [lvalue][lvalue]
calling fn with rvalue: [lvalue][rvalue]

但是如果我想制作重载模板,就像那样:

template<typename T>
void overloaded (const T& x) {std::cout << "[lvalue]";}
template<typename T>
void overloaded (T&& x) {std::cout << "[rvalue]";}

它打印

calling fn with lvalue: [rvalue][rvalue]
calling fn with rvalue: [rvalue][rvalue]

有什么方法可以使用模板函数来推导我传递给函数的对象是什么?

最佳答案

是的,这是可能的,只需将 const 添加到您的第二个重载:

template<typename T>
void overloaded (const T& x);
template<typename T>
void overloaded (const T&& x);
// ^^^^^

之所以需要 const 是为了使 x 不是转发引用。转发引用非常贪婪,如果您不传入完全相同的类型(包括任何 cv 限定符),则会选择转发引用重载。

在你的情况下,因为你没有将 const 对象传递给 overload,所以第二个重载总是更好的匹配。

但是如果你在那里添加一个 const ,那么它就不再是一个转发引用并且只能接受右值而不能接受左值,因此不会更好地匹配左值但会比 const& 重载更适合任何右值。


如果您需要从 x move ,那么您将不得不做其他事情。无论您有右值还是左值,都删除转发引用中的 const& 重载和分支:

template <typename T> void overloaded(T &&x) {
if /*constexpr*/ (std::is_lvalue_reference_v<T>)
std::cout << "[lvalue]";
else
std::cout << "[rvalue]";
}

注意:如果您执行对分支或其他分支无效的特定内容,则需要使用 if constexpr

关于C++ 模板函数中的左值和右值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50086755/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com