【问题标题】:Best viable overloaded function between std::reference_wrapper<const T> and Tstd::reference_wrapper<const T> 和 T 之间的最佳可行重载函数
【发布时间】:2021-10-22 20:45:27
【问题描述】:

最近,我决定编写一个类来存储带有 reference_wrapper 和 vector 的变体,以便选择拥有该值或仅具有它的引用。即std::variant&lt;vector&lt;string&gt;, reference_wrapper&lt;const vector&lt;string&gt;&gt;&gt;

有趣的部分是变体根据初始化存储的内容。 我做了一个小的investigation,结果证明,在所有情况下vector&lt;string&gt; 类型都获胜,除了通过std::cref 传递的情况。这同样适用于函数(有点意料之中,因为构造函数在这方面类似于函数)

void f(vector<string>); // #1
void f(reference_wrapper<const vector<string>>); // #2

vector<string> data;
const vector<string>& get_data();

f(data); // #1
f(std::cref(data)) // #2

f(get_data()); // #1
f(std::cref(get_data())) // #2

问题是为什么vector&lt;string&gt; 在这里有优先权。我查看了 最佳可行功能 部分 here ,但没有多大意义。看来,

4) or, if not that, F1 is a non-template function while F2 is a template specialization

部分选择vector&lt;string&gt; 而不是reference_wrapper&lt;vector&lt;string&gt;&gt;(因为reference_wrapper 构造函数是模板化的),但我不确定,因为使用规则我无法完全理解它们是否相等

1) There is at least one argument of F1 whose implicit conversion is better than the corresponding implicit conversion for that argument of F2

有人可以描述每种情况下应用的所有隐式转换,并说明一个重载优于另一个重载的真正原因吗?对我来说,它们如下:

f(data) = f(vector<string>&) -> (*exact match* implicit conversion) -> f(vector<string>)

f(data) = f(vector<string>&) -> (*conversion* implicit conversion) -> f(reference_wrapper<vector<string>>)

我错过了什么吗?

另一个问题,与该主题相关:隐式转换序列的排名部分again,here 留下一个问题,T(const T&amp;) 是否被视为完全匹配(用户定义类类型转换为同一类)或转换

【问题讨论】:

    标签: c++ overload-resolution reference-wrapper


    【解决方案1】:

    绝对没有理由存储reference_wrapper。只需像任何理智的程序员一样使用指针。 reference_wrapper 用于正确触发std::invoke 和相关的类/函数,如threadbind

    【讨论】:

    • 是的,你是对的,但是reference_wrapper保证里面没有nullptr,这样很方便。
    • 呃,没有理由吗?您提到的实用程序确实存储它。那是他们的咒语,将所有内容复制到内部存储中。不知道 OP 到底在做什么,但“没有理由”根本不是真的。
    • @koleydoscope 缺少默认构造函数在 IMO 中比成为 null 的可能性更糟糕——更不用说你已经有一个变体了——这意味着你已经需要进行检查。如果您真的想要一个“非零”指针而不是编写一个接受指针并在nullptr 上断言的类non_zero_ptr。这样,您还可以清楚地区分变量何时获取向量和何时获取引用 - 如果您给它一个指针或实例。
    • @StoryTeller-UnslanderMonica 您应该尝试理解人们所暗示的内容,而不是从字面上理解。故意曲解这种方式并不是特别有用。
    • 这并没有回答这个问题,这是关于重载解决规则的问题,而不是使用 reference_wrapper 是否是一个好主意,或者是否存在替代方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2016-01-23
    • 1970-01-01
    • 2013-07-21
    • 2012-04-30
    • 2014-07-21
    • 1970-01-01
    相关资源
    最近更新 更多