📜  C++中的reference_wrapper(1)

📅  最后修改于: 2023-12-03 14:39:57.247000             🧑  作者: Mango

C++中的reference_wrapper

在C++中,reference_wrapper是一个模板类,主要用于在函数中传递引用参数时,使得该引用参数可以被赋值。

reference_wrapper的定义

reference_wrapper的定义可以在头文件<functional>中找到,其定义如下:

template< class T > class reference_wrapper;

reference_wrapper是一个模板类,其模板参数T必须是一个对象类型,不能是引用类型。reference_wrapper对象的初始化可以通过以下两种方式来完成:

// 通过引用初始化
T someObject;
std::reference_wrapper<T> r1(someObject);

// 通过指针初始化
T *ptr = new T();
std::reference_wrapper<T> r2(*ptr);
reference_wrapper的用途

reference_wrapper主要用于在函数中传递引用参数时,使得该引用参数可以被赋值。通常情况下,在函数中传递引用参数时,如果需要对该引用参数进行赋值操作,则应该将该参数声明为非const引用类型。但是,在某些场景下,我们不希望函数对该参数进行修改,而只是希望该参数可以被赋值。此时,我们可以使用reference_wrapper来传递该参数,如下所示:

void func(std::reference_wrapper<int> value)
{
    value.get() = 100;  // 可以对value进行赋值操作,但是无法修改原始参数
}

int main()
{
    int value = 10;
    func(value);  // 通过reference_wrapper传递value参数
    std::cout << value << std::endl;  // 输出 100
    return 0;
}

上述代码中,我们定义了一个函数func,该函数的参数类型为std::reference_wrapper<int>。在函数中,我们可以通过value.get()方法获取到该参数的具体值,并对其进行赋值操作。但是,我们无法通过value参数来修改原始值,因为该参数是一个reference_wrapper对象。

reference_wrapper的注意事项

在使用reference_wrapper时,需要注意以下几点:

  • reference_wrapper对象必须通过引用或指针来初始化。
  • reference_wrapper对象的初始化不能使用临时对象。
  • reference_wrapper对象不能被拷贝或赋值,只能通过拷贝构造函数进行初始化。

下面的代码展示了一些reference_wrapper的使用注意事项:

void func(std::reference_wrapper<int> value)
{
    value.get() = 100;
}

int main()
{
    // reference_wrapper对象必须通过引用或指针来初始化
    int value1 = 10;
    std::reference_wrapper<int> r1(value1);

    int *value2 = new int();
    std::reference_wrapper<int> r2(*value2);

    // reference_wrapper对象的初始化不能使用临时对象
    // std::reference_wrapper<int>(10);  // 编译错误

    // reference_wrapper对象不能被拷贝或赋值,只能通过拷贝构造函数进行初始化
    // std::reference_wrapper<int> r3 = r1;  // 编译错误
    std::reference_wrapper<int> r3(r1);
    
    func(r1);
    std::cout << value1 << std::endl;  // 输出 100

    delete value2;
    return 0;
}
参考资料