允许使用l值引用,不允许使用r值引用作为函数参数

Allow l-value references and disallow r-value references as a function parameter?

本文关键字:引用 参数 函数 不允许 许使用      更新时间:2023-10-16

所以我有一个管理资源的类。与std::mutex类似,它有acquirerelease方法。为了成为一名优秀的RAII风格的程序员,我想实现对std::unique_lock的模拟,以防止资源永远被获取。然而,由于语义原因,acquirereleaseconst函数(请相信我)。

这意味着我的RAII类的构造函数有一个RAIIType( const T &)的签名。这个问题是,一个右值也会与此绑定。我希望能用SO的大脑来阻止这种情况的发生。

在编码方面:

class ResourceType
{
public:
   void acquire() const{}
   void release() const{}
};
template< class T >
class RAIIClass
{
public:
   RAIIClass(const T & in_t) : t(in_t) { t.acquire(); }
   ~RAIIClass() { t.release(); }
private:
   const T & t;
};
ResourceType foo() { return ResourceType(); }
int main()
{
   ResourceType x1;
   const ResourceType & x2(x1);
   {
      RAIIClass<ResourceType> x(x1); //Allowable
   }
   {
      RAIIClass<ResourceType> x(x2); //Allowable
   }
   {
      RAIIClass<ResourceType> x(foo()); //Currently allowable, would like to disallow.
   }
}

有什么想法吗?

添加此构造函数:

RAIIClass(const T&&) = delete;

这将绑定到const或非常值,其中const和非常值都更喜欢您现有的构造函数:

RAIIClass(const T & in_t) : t(in_t) { t.acquire(); }

禁止为临时对象创建管理器的另一种选择是,当使用临时对象(在Coliru演示)调用时,更改管理器类以在内部存储托管对象:

template< class T >
class RAIIClass;
template <typename T>
RAIIClass<T> make_guard(T&&);
template< class T >
class RAIIClass
{
public:
   ~RAIIClass() { t.release(); }
private:
   friend RAIIClass make_guard<>(T&&);
   RAIIClass(T&& in_t) : t(std::forward<T>(in_t)) { t.acquire(); }
   T t;
};
template <typename T>
RAIIClass<T> make_guard(T&& t)  {
   return {std::forward<T>(t)};
}
ResourceType foo() { return {}; }
int main()
{
   ResourceType x1;
   const ResourceType & x2(x1);
   {
      auto x = make_guard(x1); //Allowable
   }
   {
      auto x = make_guard(x2); //Allowable
   }
   {
      auto x = make_guard(foo()); //Allowable too.
   }
}