当两个模板都等量匹配时,函数绑定到第二个模板而不是通用引用 [duplicate]

function binds to second template instead of universal reference when both equally match [duplicate]

提问人:nvn 提问时间:11/8/2023 最后编辑:Toby Speightnvn 更新时间:11/8/2023 访问量:71

问:

这是一个比特菲德。所以我必须添加 const 如有问题i

现在它打印 lvalue。

  1. 为什么当通用参考是更好的匹配时,它会打印左值 ?

  2. 这是否意味着当我们有左值引用匹配和右值引用匹配时 lvalue ref match 总是被选中?

    #include<bits/stdc++.h>
    using namespace std;
    
    template<typename T> void f(const T&& obj){ cout <<"rvalue\n"; }
    template<typename T> void f(const T& obj){ cout <<"lvalue\n"; }
    
    struct S {
        int i:31;
        int j;
    };
    int main()
    {
        S s;
        f(s.i);
    }
    
  3. 下面我们从 f(T&& obj) 中删除 const,它将右值打印为 预期,因为两者都是匹配和通用参考 优先权。这是对的吗?

    #include<bits/stdc++.h>
    using namespace std;
    
    /* this is not constant . It is T&& instead of const T&& */
    template<typename T> void f(T&& obj){ cout <<"rvalue\n"; }
    template<typename T> void f(const T& obj){ cout <<"lvalue\n"; }
    
    struct S {
        int i:31;
        int j;
    };
    int main()
    {
        S s;
        f(s.j);
    }
    
C++ 模板 17 C ++14

评论

1赞 Jabberwocky 11/8/2023
旁注:stackoverflow.com/questions/31816095/...
2赞 Pepijn Kramer 11/8/2023
旁注:对于模板,它不是通用引用,而是转发引用。并停止使用 <bits/stdc++.h>。此外,位域可能比您想象的更棘手
0赞 user12002570 11/8/2023
@PepijnKramer 或者我会说,完全停止使用它们(位字段)。
0赞 Pepijn Kramer 11/8/2023
@user12002570 对于可移植代码,对于不可移植代码,请编写单元测试。但总而言之,不能保证内存大小(和/或内存布局),Bitfiel 只保证值 i 在算术上的行为类似于 31 位类型。
0赞 Pepijn Kramer 11/8/2023
此外,@OP只对C++使用一个版本标记。对于哪个版本,您需要答案?

答:

2赞 463035818_is_not_an_ai 11/8/2023 #1

原因是它不是转发参考(斯科特称之为“通用参考”的官方术语)。来自 cppreferenceconst T&&

转发引用是一种特殊类型的引用,它保留了函数参数的值类别,从而可以通过 std::forward 转发它。转发引用是:

  1. 函数模板的函数参数,声明为右值引用,引用同一函数模板的 CV-Unqualified 类型模板参数:[...]

const T&&不是“CV-unqualified”,因此不是转发参考。在第二个示例中,是一个转发引用。f(T&& obj)T