[英]Using decay with perfect forwarding
假設我們有兩個函數:
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};
}
我們這樣稱呼它們:
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&
盡管兩個函數中的推導相似,但在第二個函數中,我必須使用 std::decay_t 來編譯應用程序。 為什么會這樣?
我使用帶有 /std:c++17 標志的 Visual Studio 2019
當你有一個像
template <typename T> void callDecayExample1(T& t)
{
std::initializer_list<T> testList2{ 1, 2, 3 };
}
那么T
只會被推導出為非引用類型。 如果你給它一個int&
,那么T
變成int
這樣t
就變成一個int&
。 因此,您不需要使用decay
。
在
template <typename T> void callDecayExample2(T&& t)
{
std::initializer_list<std::decay_t<T>> testList{1, 2, 3};
}
如果您傳遞int&
則T
被推導出為int&
,然后引用折疊規則將int& &&
轉換為int&
類型的t
。 這意味着在沒有decay
您會嘗試制作一個您無法做到的std::initializer_list<int&>
。
說推導出的類型相同是不正確的:
#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;
}
印刷:
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&]
在您的情況下, std::decay
刪除了第二個示例中存在的額外引用。
因為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.