3

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

有趣的部分是变体根据初始化存储的内容。我做了一个小调查,结果证明,在所有情况下vector<string>,类型都会获胜,除了通过 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<string>这里有优先权。我在这里查看了最佳可行功能部分,但没有多大意义。看起来

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

部分选择(因为vector<string>构造函数是模板化的),但我不确定,因为使用规则我无法完全理解它们是否相等reference_wrapper<vector<string>>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>>)

我错过了什么?

另一个与此主题相关的问题:再次对隐式转换序列部分进行排名,这里留下一个问题,被T(const T&)认为是精确匹配(用户定义的类类型到同一类的转换)或转换

4

1 回答 1

-3

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

于 2021-08-21T21:07:09.267 回答