[英]Using decay with perfect forwarding
Assume we have 2 functions:假设我们有两个函数:
template <typename T> void callDecayExample1(T& t)
{
std::initializer_list<T> testList2{ 1, 2, 3 };
}
template <typename T> void callDecayExample2(T&& t)
{
std::initializer_list<std::decay_t<T>> testList{1, 2, 3};
}
and we call them like this:我们这样称呼它们:
const int& i = 2;
int j = 10;
int& ref_j = j;
callDecayExample1(i); // deduced as const int&
callDecayExample1(ref_j);// deduced as int&
callDecayExample1(j); // deduced as int&
callDecayExample2(i); // deduced as const int&
callDecayExample2(ref_j);// deduced as int&
callDecayExample2(j); // deduced as int&
depspite the similar deducing in both functions, in the 2nd function I have to use std::decay_t to compile the application.尽管两个函数中的推导相似,但在第二个函数中,我必须使用 std::decay_t 来编译应用程序。 Why it is so?
为什么会这样?
I use Visual studio 2019 with the /std:c++17 flag我使用带有 /std:c++17 标志的 Visual Studio 2019
When you have a function like当你有一个像
template <typename T> void callDecayExample1(T& t)
{
std::initializer_list<T> testList2{ 1, 2, 3 };
}
then T
is only going to get deduced as a non reference type.那么
T
只会被推导出为非引用类型。 If you give it a int&
, then T
becomes int
so that t
becomes a int&
.如果你给它一个
int&
,那么T
变成int
这样t
就变成一个int&
。 Because of that you do not need to use decay
.因此,您不需要使用
decay
。
In在
template <typename T> void callDecayExample2(T&& t)
{
std::initializer_list<std::decay_t<T>> testList{1, 2, 3};
}
If you pass a int&
then T
gets deduced as a int&
, and then reference collapsing rules turn int& &&
into int&
for the type of t
.如果您传递
int&
则T
被推导出为int&
,然后引用折叠规则将int& &&
转换为int&
类型的t
。 This means that without decay
you would try to make a std::initializer_list<int&>
which you can't do.这意味着在没有
decay
您会尝试制作一个您无法做到的std::initializer_list<int&>
。
It is not correct to say that the deduced types are identical:说推导出的类型相同是不正确的:
#include <iostream>
template <typename T>
void printType()
{
std::cerr << __PRETTY_FUNCTION__ << std::endl;
}
template <typename T>
void callDecayExample1(T& t)
{
printType<T>();
std::initializer_list<T> testList2{1, 2, 3};
}
template <typename T>
void callDecayExample2(T&& t)
{
printType<T>();
std::initializer_list<std::decay_t<T>> testList{1, 2, 3};
}
int main()
{
const int i = 0;
int j = 1;
int& ref_j = j;
callDecayExample1(i);
callDecayExample1(ref_j);
callDecayExample1(j);
callDecayExample2(i);
callDecayExample2(ref_j);
callDecayExample2(j);
return 0;
}
prints:印刷:
void printType() [with T = const int]
void printType() [with T = int]
void printType() [with T = int]
void printType() [with T = const int&]
void printType() [with T = int&]
void printType() [with T = int&]
In your situation std::decay
removes the extra reference that is present in the second example.在您的情况下,
std::decay
删除了第二个示例中存在的额外引用。
Because T
may or may not be a reference type:因为
T
可能是也可能不是引用类型:
template <typename T> void callDecayExample2(T&& t)
{
if constexpr (std::is_same<T, int&>::value)
std::initializer_list<std::decay_t<T>> testList{ 1, 2, 3 };
else
std::initializer_list<T> testList{ 1, 2, 3 };
}
int val = 5;
callDecayExample2(5) // T = int
callDecayExample2(val) // T = int&
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.