最近,我决定编写一个类来存储带有 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&)
认为是精确匹配(用户定义的类类型到同一类的转换)或转换?