如果我通过通用引用接受参数,那么 is_rvalue_reference 和 is_lvalue_reference 中的一个是否正确?
If I accept a parameter via universal reference, is exactly one of is_rvalue_reference and is_lvalue_reference true?
此代码是否可能打印 "neither"?
using namespace std;
template<typename T>
void foo(T&& t) {
if constexpr (is_lvalue_reference_v<T>) {
cout << "lv" << endl;
} else if constexpr (is_rvalue_reference_v<T>) {
cout << "rv" << endl;
} else {
cout <<"neither" << endl;
}
}
Is it ever possible for this code to print "neither"?
是的。
foo(5); // neither
If I accept a parameter via universal reference, is exactly one of is_rvalue_reference and is_lvalue_reference true?
参数 t
将具有右值引用类型或左值引用类型。另一方面,类型 T
将根据推导和 reference collapsing 规则而有所不同。相反,如果您将 is_lvalue/rvalue_reference<T>
更改为 is_lvalue/rvalue_reference<decltype(t)>
,则永远不会执行 else 路径。
Is it ever possible for this code to print "neither"?
是的,只要将右值传递给 foo
且未给出显式模板参数,就会打印 "neither":
foo(42); // "neither" is printed because T is deduced as int
或者当明确指定 non-reference 类型时:
int i=0;
// "neither" is printed because T is explicitly specified as int:
foo<int>(std::move(i));
虽然 T
可以是 non-reference 类型,但 t
的类型将始终是引用类型。 t
的类型有三种可能:
T
是值类型(即int
):t
的类型是int&&
; rvalue-reference 到 int
.
T
是一个lvalue-reference(即int&
):t
的类型是int& &&
,折叠成int&
; lvalue-reference 到 int
.
T
是一个rvalue-reference(即int&&
):t
的类型是int&& &&
,折叠成int&&
; rvalue-reference 到 int
.
这是转发引用的工作机制。如果将右值传递给 foo
,则 T
将被推断为值类型。如果您传递左值,则 T
将被推断为 lvalue-reference 类型。
Is it ever possible for this code to print "neither"?
是的。根据forwarding reference的类型推导规则,当传递左值时,T
将推导为lvalue-reference类型,当传递右值时,将推导T
作为 non-reference 类型。例如
int i;
foo(i); // T is deduced as int&
foo(0); // T is deduced as int
另一方面,除非明确指定模板参数,否则不会打印 "rv"
。
另一方面(再次),如果您检查函数参数的类型 t
,它将是 lvalue-reference 类型或 rvalue-reference 类型; "neither"
都不会打印。
int i;
foo(i); // T is deduced as int&, the type of t is int& (int& && -> int&)
foo(0); // T is deduced as int, the type of t is int&&
foo<int&&>(0); // T is specified as int&&, the type of t is int&& (int&& && -> int&&)
此代码是否可能打印 "neither"?
using namespace std;
template<typename T>
void foo(T&& t) {
if constexpr (is_lvalue_reference_v<T>) {
cout << "lv" << endl;
} else if constexpr (is_rvalue_reference_v<T>) {
cout << "rv" << endl;
} else {
cout <<"neither" << endl;
}
}
Is it ever possible for this code to print "neither"?
是的。
foo(5); // neither
If I accept a parameter via universal reference, is exactly one of is_rvalue_reference and is_lvalue_reference true?
参数 t
将具有右值引用类型或左值引用类型。另一方面,类型 T
将根据推导和 reference collapsing 规则而有所不同。相反,如果您将 is_lvalue/rvalue_reference<T>
更改为 is_lvalue/rvalue_reference<decltype(t)>
,则永远不会执行 else 路径。
Is it ever possible for this code to print "neither"?
是的,只要将右值传递给 foo
且未给出显式模板参数,就会打印 "neither":
foo(42); // "neither" is printed because T is deduced as int
或者当明确指定 non-reference 类型时:
int i=0;
// "neither" is printed because T is explicitly specified as int:
foo<int>(std::move(i));
虽然 T
可以是 non-reference 类型,但 t
的类型将始终是引用类型。 t
的类型有三种可能:
T
是值类型(即int
):t
的类型是int&&
; rvalue-reference 到int
.T
是一个lvalue-reference(即int&
):t
的类型是int& &&
,折叠成int&
; lvalue-reference 到int
.T
是一个rvalue-reference(即int&&
):t
的类型是int&& &&
,折叠成int&&
; rvalue-reference 到int
.
这是转发引用的工作机制。如果将右值传递给 foo
,则 T
将被推断为值类型。如果您传递左值,则 T
将被推断为 lvalue-reference 类型。
Is it ever possible for this code to print "neither"?
是的。根据forwarding reference的类型推导规则,当传递左值时,T
将推导为lvalue-reference类型,当传递右值时,将推导T
作为 non-reference 类型。例如
int i;
foo(i); // T is deduced as int&
foo(0); // T is deduced as int
另一方面,除非明确指定模板参数,否则不会打印 "rv"
。
另一方面(再次),如果您检查函数参数的类型 t
,它将是 lvalue-reference 类型或 rvalue-reference 类型; "neither"
都不会打印。
int i;
foo(i); // T is deduced as int&, the type of t is int& (int& && -> int&)
foo(0); // T is deduced as int, the type of t is int&&
foo<int&&>(0); // T is specified as int&&, the type of t is int&& (int&& && -> int&&)