std::reference_wrapper<const T> 和 T 之间的最佳可行重载函数



>最近,我决定编写一个类,存储带有 reference_wrapper

首先,尽管std::reference_wrapper是标准库的一部分,但它被视为用户定义类型。

例如,从std::vector &const std::vector &的隐式转换始终优于从std::vector&std::reference_wrapper<vector>的隐式转换。这是因为(根据标准)前者是标准转换,但后者是用户定义的转换。第一个称为标准转换,因为它为您的类型添加了const,但第二个被视为将某种类型转换为完全不同的类型。

检查此代码并查看 cppreference.com。

其次,我试图猜测一些好的选择。我看到您希望存储对向量的引用或移动/(尽可能便宜地复制)或者(您可以说直接初始化)类中的数据,如果它尚未(安全地)存储在某个变量中。也许您可以考虑使用移动语义。你可以在这里玩代码

using TVar = std::variant<reference_wrapper<const vector<string>>, vector<string>>;
class Config {
private:
TVar data;
public:
const vector<string>& get_data() const{
if (data.index() == 1)
return get<1>(data);
else return get<0>(data);
}
Config(const vector<string>& it):data(cref(it)){}
Config(vector<string>&& it):data(move(it)){}
};

这里我们有两个功能。

  1. 一个引用"储值"(更准确地说是左值)的方法。 将其包装在 cref 中,以便使变体中的reference_wrapper替代方案成为最佳重载。
  2. 另一个做魔术。 它是对直接写入的值(也称为 pvalues )和使用魔术std::move函数的值(也称为 xvalues )的引用。 如果你从未见过这个,请参考这个受人尊敬的问答 什么是移动语义?

catch(...):),就是这样。 另请注意,您不需要std::monostate,因为这仅在使变体默认可构造(没有参数)时才需要。 你可以像这样使类默认可构造。

Config(vector<string>&& it = {}):data(move(it)){}

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

相关内容

  • 没有找到相关文章

最新更新