英文:
Function that can receive any of T, T&, and T&& as input, AND also recognize its type?
问题
以下是翻译好的代码部分:
template<class T> void test(T&& t){
if constexpr(std::is_same_v<T, int>){
std::cout<< "= int"<<std::endl;
}
if constexpr(std::is_same_v<T, const int&>){
std::cout<< "= const int&"<<std::endl;
}
if constexpr(std::is_same_v<T, int&>){
std::cout<< "= int&"<<std::endl;
}
if constexpr(std::is_same_v<T, int&&>){
std::cout<< "= int&&"<<std::endl;
}
if constexpr(std::is_same_v<T, std::nullptr_t>){
std::cout<< "= std::nullptr_t"<<std::endl;
}
}
int funcReturnInt(){return 5;}
int main(){
const int a=0;
test(funcReturnInt()); // int (correct)
test(a); // const int& (correct)
test(nullptr); // std::nullptr_t (correct)
int s=0;
test(std::move(s)); // print "int" (not "int&&") , I am sad
}
希望这对你有所帮助。
英文:
I want to create a function that correctly recognizes the type of its parameter.
template<class T> void test(T&& t){
if constexpr(std::is_same_v<T,int>){
std::cout<< "= int"<<std::endl;
}
if constexpr(std::is_same_v<T,const int&>){
std::cout<< "= const int&"<<std::endl;
}
if constexpr(std::is_same_v<T,int&>){
std::cout<< "= int&"<<std::endl;
}
if constexpr(std::is_same_v<T,int&&>){
std::cout<< "= int&&"<<std::endl;
}
if constexpr(std::is_same_v<T,std::nullptr_t>){
std::cout<< "= std::nullptr_t"<<std::endl;
}
}
int funcReturnInt(){return 5;}
int main(){
const int a=0;
test(funcReturnInt()); // int (correct)
test(a); // const int& (correct)
test(nullptr); // std::nullptr_t (correct)
int s=0;
test(std::move(s)); // print "int" (not "int&&") , I am sad
}
How to create the test()
function so it can recognize the type of its single parameter correctly in every case?
I am new to T&&
, so I have read some guides about rvalue references (1, 2, 3), but they don't describe how to create such a full-awareness wildcard function like test<T>(T??)
.
I will apply the solution as test() requires ... {}
later.
I prefer to avoid overloading, because I love to make the code compact in 1 place (for educational purpose, too).
Edit :: Very useful comments state that it is generally not possible. Why does my code check other cases correctly, but C++ takes a liberty to get rid of my &&
? Please post it as a solution.
I still doubt why int&
in main()
becomes T=int&
correctly but int&&
in main()
becomes T=int
.
答案1
得分: 2
-
我是新手,所以我阅读了一些关于 rvalue references(1, 2, 3)的指南,但它们没有描述如何创建一个完全意识到的通配符函数,比如
test<T>(T??)
。 -
在这个声明中:
template<class T> void test(T&& t)
尽管常常被误认为是一个,但
t
不是一个右值引用,它是转发引用(有时称为通用引用)。要理解转发引用,我们需要了解更多关于右值引用的内容,例如 引用折叠 规则和完美转发。详情请参见以下问答: -
我仍然怀疑为什么
main()
中的int&
变成了T=int&
,但main()
中的int&&
变成了T=int
。 -
在调用中:
test(std::move(s));
参数类型 A 是
int&&
,完整的参数类型是int&&
,这意味着推断出的T
是int
test<int>(int&& t);
参考详情,请参见 [temp.deduct.call]/3。
-
通用引用在参数类型是左值时特别适用于引用折叠规则。对于调用
test(a)
,参数类型是int const
,但为了推断的目的,将int const&
用于推断T
为int const&
,其中生成的函数参数类型T&&
从int const&& &&
折叠为int const&
(&& &
->&
)。
英文:
Emphasis mine:
> I am new to T&&
, so I have read some guides about rvalue references (1, 2, 3), but they don't describe how to create such a full-awareness wildcard function like test<T>(T??)
.
In this declaration:
> template<class T> void test(T&& t)
whilst commonly mistaken for one, t
is not an rvalue reference, it is forwarding reference (sometimes referred to as universal references). To understand forwarding references we need to understand more than rvalue references, e.g. reference collapsing rules and perfect forwarding. See e.g. the following Q&A for details:
> I still doubt why int&
in main() becomes T=int&
correctly but int&&
in main()
becomes `T=int.
In the call
> test(std::move(s));
the argument type A is int&&
, the complete parameter type is int&&
meaning the deduced T
is int
test<int>(int&& t);
^^^ ^^^^^ parameter-type (T&& -> int&&)
\ deduced T
Refer to e.g. [temp.deduct.call]/3 for details.
Universal references particularly apply reference collapsing rules when the argument type is an lvalue. For the call test(a)
the argument type is int const
, but for purposes of deduction, int const&
is used in place, deducing T
to int const&
, where the resulting function parameter type T&&
is collapsed from int const& &&
to int const&
(&& &
-> &
).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论