繁体   English   中英

使用std :: reference_wrapper <const T> 处理构造函数中的const T&-合适吗?

[英]Use std::reference_wrapper<const T> to handle const T& in constructor - appropriate?

一个类拥有一个类型为U的对象。 通过一种方法,它使用吸气剂将此对象公开为const U& (不是可廉价复制的,不需要修改)。

现在,客户端希望使用此API。 他希望将U的实例用作复杂对象的一部分(对更改API对象没有兴趣)。 因此,他至少有以下几个选项:创建一个类Tconst U&作为参数和类型的私有字段const U&这里的构造函数存储API的实例。 这具有极端的缺点,即使类的实例非常不灵活(例如,不使用std :: vectors进行管理),这是不希望的。

不久前,我发现还可以使用std::reference_wrapper<const U>来存储const U& ,这不会对T类型的实例施加这些不利影响。

现在的问题是,这样做的行为是否像预期的那样,是一种好的做法?

在下面以及这里 ,您可以找到使用此策略和描述的类型的有效代码。

#include <iostream>
#include <memory>

class U{
    public: 
    uint value;
};

class T{
private:
    std::reference_wrapper<const U> _u;

public:
    T(const U& u)
        :_u(u) {}

    const U& GetU(){
        return _u;
    }
};

const U& provideValue(U& u){
    return u;
}

int main()
{
    U internalApiValue;
    internalApiValue.value = 5;

    auto apiValue = provideValue(internalApiValue);

    T container(apiValue);

    std::cout << container.GetU().value;
}

我想如果这不是一个好主意,唯一的选择就是避免使用const,因为否则我会对此类方法的用户施加严格的限制(公开const U&而不是U&U )?

接口的一个主要问题是T的唯一构造函数采用const U& 这意味着您可以将一个临时变量传递给T并使用reference_wrapper保留给一个失效的对象,因为对象中的const&不会延长该临时变量的寿命。

为了解决这个问题,您需要添加一个删除的构造函数,以阻止您接受临时对象。 添加

T(const U&&) = delete;

会做到的。

这应该做您想要的。 它以预期使用的方式使用std::reference_wrapper<T> (以使引用可复制和可分配的方式传递引用)。 我没有发现任何问题。 来自cppreference.com

std :: reference_wrapper是一个类模板,它将引用包装在可复制的可分配对象中。 它通常用作将引用存储在通常无法保存引用的标准容器(如std :: vector)内的机制。

我看到的唯一潜在的缺点是std::reference_wrapper<T>可能有点难以使用并且对某些人并不熟悉。 解决您的问题的更常见方法可能是将指针存储在对象中,而不是引用中。 例如:

class T {
private:
    const U* _u;

public:
    T(const U& u)
        : _u(&u) {}
    …
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM