c++ 模板类存储具有相同模板参数的引用或值

问题描述 投票:0回答:2

我想设计一个可以存储值或引用的类,但在模板声明中具有相同的参数。我不知道如何编写模板类。谁能给我一些建议吗

tempalte <typename T>
class Holder {

// ......
Holder(T &value);
Holder(T value);

}

class CannotCopy {

CannotCopy(CannotCopy const&) = delete;

};

Holder<CannotCopy> holder1(CannotCopy())

CannotCopy cannot_copy;

Holder<CannotCopy> holder2(cannot_copy) // passed by reference


c++ templates
2个回答
1
投票

因此,如果我理解正确的话,您有时希望该类拥有您传递给它的元素的所有权(当就地构造时),有时您希望将其用作对存储在其他地方的所有权的引用。

不幸的是,当我告诉你这是一个坏主意时,我是根据经验说话的。乍一看,这看起来是个好主意,但是,经过几个抽象层之后,您最终会得到无法推理所有权的代码。

一种方法是在参数的右值/左值上重载构造函数:

template <typename T>
class Holder {
 public:
  Holder(T &&value)
      : m_ownership{std::make_unique<T>(std::move(value))},
        m_value{*m_ownership} {}
  Holder(T &value) : m_value{value} {}

 private:
  std::unique_ptr<T> m_ownership;
  T &m_value;
};

编译器资源管理器中的代码

如您所见,现在有一个带有

T &&
的构造函数,它允许您将右值传递给它并移动它。 (假设移动构造函数可用,这通常是不可复制的情况) 这将知道它需要所有权并将该值存储为 unique_ptr,然后在 m_value 中传递 unique_ptr 内部值的引用。

如果您使用左值调用构造函数,它只是将其放入 m_value 中,而不使用 unique_ptr 作为所有权。

这样,您的班级就有该值的有条件所有权。如果您不喜欢 unique_ptr 占用空间,您可以(如果对齐允许 -> 您可以强制执行一些位操作)进行一些位操作来编码(无论您是否拥有所有权)并编写一堆自定义代码。


0
投票

用户定义的推导指南似乎可以解决问题。

template<class T>
struct Holder{
    T value;
};

template<class T>
Holder(T&&) -> Holder<T>;

请注意,您应该在不明确指定

CannotCopy
的情况下初始化变量,以便让推导指南完成其工作。

Holder holder1{CannotCopy()};

CannotCopy cannot_copy;

Holder holder2{cannot_copy}; // passed by reference

另请参阅构造函数调用的 godbolt 演示

© www.soinside.com 2019 - 2024. All rights reserved.