我想创建一个能够正确识别其参数类型的函数。
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
}
如何创建test()
函数以便在每种情况下都能正确识别其单个参数的类型?
我是 T&&
的新手,所以我阅读了一些关于右值引用的指南( 1 、 2 、 3 ),但它们没有描述如何创建像 test<T>(T??)
这样的全感知通配符函数。 .
我将应用解决方案 test() requires ... {}
稍后。
我更喜欢避免重载,因为我喜欢将代码紧凑地集中在一处(也出于教育目的)。
编辑::非常有用的评论指出这通常是不可能的。为什么我的代码可以正确检查其他情况,但 C++ 却擅自删除我的 &&
?请将其作为解决方案发布。
我仍然怀疑为什么int&
在main()
变成T=int&
正确,但是 int&&
在main()
变成T=int
.
最佳答案
强调我的:
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 liketest<T>(T??)
.
在此声明中:
template<class T> void test(T&& t)
虽然经常被误认为是 t
不是右值引用,它是转发引用(有时称为通用引用)。要理解转发引用,我们需要了解的不仅仅是右值引用,例如reference collapsing规则和完美转发。参见例如详情请参阅以下问答:
I still doubt why
int&
in main() becomesT=int&
correctly butint&&
inmain()
becomes `T=int.
通话中
test(std::move(s));
参数类型 A 是 int&&
,完整的参数类型为int&&
意思是推导出来的T
是 int
test<int>(int&& t);
^^^ ^^^^^ parameter-type (T&& -> int&&)
\ deduced T
引用例如[temp.deduct.call]/3了解详情。
当参数类型为左值时,通用引用特别适用引用折叠规则。如需调用test(a)
参数类型为int const
,但是对于 purposes of deduction , int const&
就地使用,推导出 T
至int const&
,其中生成的函数参数类型 T&&
已从 int const& &&
折叠至int const&
( && &
-> &
)。
关于c++ - 可以接收 T、T& 和 T&& 中的任何一个作为输入的函数,并且还可以识别其类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76873361/