c++ - 可以接收 T、T& 和 T&& 中的任何一个作为输入的函数,并且还可以识别其类型?

标签 c++ rvalue-reference if-constexpr

我想创建一个能够正确识别其参数类型的函数。

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&& 的新手,所以我阅读了一些关于右值引用的指南( 123 ),但它们没有描述如何创建像 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 like test<T>(T??).

在此声明中:

template<class T> void test(T&& t)

虽然经常被误认为是 t不是右值引用,它是转发引用(有时称为通用引用)。要理解转发引用,我们需要了解的不仅仅是右值引用,例如reference collapsing规则和完美转发。参见例如详情请参阅以下问答:

I still doubt why int& in main() becomes T=int& correctly but int&& in main() becomes `T=int.

通话中

test(std::move(s));

参数类型 A 是 int&& ,完整的参数类型为int&&意思是推导出来的Tint

test<int>(int&& t);
     ^^^  ^^^^^ parameter-type (T&& -> int&&)
       \ deduced T

引用例如[temp.deduct.call]/3了解详情。

当参数类型为左值时,通用引用特别适用引用折叠规则。如需调用test(a)参数类型为int const ,但是对于 purposes of deduction , int const&就地使用,推导出 Tint const& ,其中生成的函数参数类型 T&&已从 int const& && 折叠至int const& ( && & -> & )。

关于c++ - 可以接收 T、T& 和 T&& 中的任何一个作为输入的函数,并且还可以识别其类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76873361/

相关文章:

c++ - Unittest++ 不识别测试

c++ - 为什么 int foo() 是右值,而 int& foo() 在这个例子中是左值?

c++ - std::thread 和右值引用

c++ - "if constexpr"与 "try in constexpr function"警告交互

c++ - constexpr if 的等效三元运算符?

c++ - 如果为 false,则 std::is_member_function_pointer 不编译

c++ - 在 postgres 中生成唯一 ID

c++ - 实现 std::error_category,与自定义命名空间一起使用时的名称解析问题

c++ - 通过c中的指针传递二维数组时出错

c++ - 命名右值引用的类型是什么?