通过不同的容器修改std容器的内容

2024-03-08

我不知道这是否是正确的方法,但我认为它解释了我想要实现的目标。

我有三个向量:

std::vector<int> v1 = {1,2,3};
std::vector<int> v2 = {5,6,7};
std::vector<int> v3 = {8,9,10};

我想创建一个包含对这些向量的第一个元素的引用的向量,我尝试按如下方式执行此操作:

std::vector<std::reference_wrapper<int>> v;
v.push_back(v1[0]);
v.push_back(v2[0]);
v.push_back(v3[0]);

所以我可以这样做:

std::rotate(v.begin(),v.begin+1,v.end())

and get:

v1 = 5, 2, 3
v2 = 8, 6, 7
v3 = 1, 9, 10

它几乎可以工作,执行以下操作会修改原始向量:

++v[0];

但赋值不起作用:

v[0] = new_value; // doesn't compile

Nor std::rotate有什么影响。

我怎样才能做到这一点?

Code

#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>

void print_vector(std::vector<int> &v) {
    std::for_each(v.begin(),v.end(),[](auto& x){std::cout << x << " ";});
    std::cout << "\n";
}

int main() {

    std::vector<int> v1 = {1,2,3};
    std::vector<int> v2 = {5,6,7};
    std::vector<int> v3 = {8,9,10};

    std::vector<std::reference_wrapper<int>> v;

    v.push_back(v1[0]);
    v.push_back(v2[0]);
    v.push_back(v3[0]);

    // This doesn't work, it rotates the references but not the values
    std::rotate(v.begin(),v.begin()+1,v.end());
    print_vector(v1);
    print_vector(v2);
    print_vector(v3);

    // Never the less this does work
    ++v[0];
    print_vector(v1);
    print_vector(v2);
    print_vector(v3);

    //v[0] = 3; // Assigment doesn't compile


    return 0;
}

的赋值运算符std::reference_wrapper (std::reference_wrapper::operator= http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper) 不会为引用的元素分配新值,而是重新绑定包装器。所以基本上:

std::vector<std::reference_wrapper<int>> v;
int a = 0;
v[0] = a;

assert( &v[0].get() == &a ); // true

如果要为引用的元素分配新值,则需要明确:

v[0].get() = a;

如果你想v[0] = a;按照您的预期工作,甚至std::rotate(因为它实际上交换引用,而不是值),您可以编写自己的包装器:

/**
 * Class implementing std::reference_wrapper that
 * cannot be rebound after creation.
 *
 **/
template <class T>
class single_bind_reference_wrapper {

    // pointer to the original element
    T *p_;

public: // typedefs

    using type = T;

    // construct/copy/destroy
    single_bind_reference_wrapper(T& ref) noexcept : p_(std::addressof(ref)) {}
    single_bind_reference_wrapper(T&&) = delete;

    // Enable implicit convertsion from ref<T> to ref<const T>,
    // or ref<Derived> to ref<Base>
    template <class U, std::enable_if_t<std::is_convertible<U*, T*>{}, int> = 0>
    single_bind_reference_wrapper(const single_bind_reference_wrapper<U>& other) noexcept :
        p_(&other.get()) { }

    // assignment
    template <class U>
    decltype(auto) operator=(U &&u) const 
          noexcept(std::is_nothrow_assignable<T, U>{}) {
        return get() = std::forward<U>(u);
    }

    decltype(auto) operator=(const single_bind_reference_wrapper& other) const
          noexcept(std::is_nothrow_assignable<T, T>{}) {
        return get() = other.get();
    }


    // access
    operator T& () const noexcept { return *p_; }
    T& get() const noexcept { return *p_; }
};

您需要提供一个自定义的swap大多数算法正常工作的函数,例如:

template <class T>
void swap(single_bind_reference_wrapper<T> &lhs,
          single_bind_reference_wrapper<T> &rhs)
    noexcept(std::is_nothrow_move_constructible<T>::value &&
             std::is_nothrow_move_assignable<T>::value){
    auto tmp = std::move(lhs.get());
    lhs = std::move(rhs.get());
    rhs = std::move(tmp);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过不同的容器修改std容器的内容 的相关文章

随机推荐

  • 如何在 Python 中压缩字符串

    我正在制作一个 python 脚本 将字符串发送到 Web 服务 在 C 中 我需要压缩或压缩这个字符串 因为带宽和 MB 数据是有限的 是的 大写 因为它非常有限 我正在考虑将其转换为文件 然后压缩该文件 但我正在寻找一种直接压缩字符串的
  • 为什么 Backbone Collection fetch 不返回承诺

    下面的示例代码运行良好 Auth controller prototype isLogged function Check if the user is authenticated var getAuthStatus this auth m
  • IE10 中本地存储的访问被拒绝

    昨天我安装了 Windows 8 现在试图了解为什么我在访问本地存储时收到 访问被拒绝 消息 该页面与浏览器 http localhost 位于同一台 PC 上 我的感觉是IE 10中的一项安全设置是错误的 但我还没弄清楚是哪一项 触发错误
  • 将 html 附加到指令中的元素并创建一个与其交互的本地函数

    在我的 AngularJS 应用程序中 我到处都有不同的复杂输入 例如 某些输入具有使用 Google Places 自动完成功能或 Twitter Bootstrap 自动完成功能的指令 我正在寻找一种方法来制作一个指令 当我们添加一些文
  • 使用箭头键浏览 JButton

    我做了一个JButton数组 代表卡片 共有 16 张 4 4 我怎样才能在其中浏览JButton使用键盘上的箭头而不是鼠标 我如何 单击 JButton按 ENTER 键而不是单击鼠标 也许有另一种方法可以做到这一点而不是使用JButto
  • 将 root 中的默认 python 更改为 anaconda 的 python

    我已经在我的系统中安装了 python 2 7 并且还安装了 Anaconda 现在 我正在使用 python 的 anaconda 它运行得很好 不幸的是 我想使用anaconda的python来使用root运行 问题是我无法更改 roo
  • 仅允许接下来的 5 个工作日 jquery datepicker

    我有一个日期选择器 用于设置约会 唯一的问题是老板希望预约日期仅限于接下来的 5 个工作日 我知道如何禁用周末 但我有点不清楚如何做到这一点 以便如果我选择周三 它可以让我选择下周三之前的日期并考虑周末 有人对如何实现这一目标有任何想法吗
  • 无法使用完成处理程序进行抛出操作

    我正在尝试添加一个throws使用完成处理程序添加到我现有的函数 但我不断收到警告说no calls throwing functions occur within try expression 在我抛出错误的部分中 我收到一条错误消息 从
  • 使用 UIBezierPath 绘制圆角

    我有一个设计元素无法弄清楚 希望有人能够指出我正确的方向 我试图构建的元素是这样的 实际上 它是一个圆角矩形 在左侧 顶部和右侧都有描边 底部应该没有描边 我尝试过使用以下代码 Create the rounded rectangle le
  • 如何优化这个 GORM 查询

    我有一个查询 它进行 2 个数据库查询 我是 GORM 的新手 不知道如何使用条件 where 子句或其他内容将其优化为 1 个查询 我也使用 springsecurity 并有一个用于登录安全的 User 类 我有一个带有 User 对象
  • 在特定时间后台获取

    我正在寻找即使应用程序终止也能在后台模式下获取数据的解决方案 对于这个问题有很多教程和答案 但我的问题与其他问题不同 我在 stackoverflow 上没有找到任何合适的解决方案 所以发布了这个问题 我有一个可以解释的场景 我正在使用存储
  • Nhibernate:以相同的精度和小数位映射所有小数

    据我了解 在 NHibernate 中 使用代码映射 我可以指定小数属性的精度和小数位数 如下所示 Property x gt x Dollars m gt m Precision 9 m Scale 6 这很好 但我想知道是否有一种方法可
  • Clojure 的动态变量和绑定的实际用途是什么?

    我看了一下参考资料 http clojure org vars Vars 20and 20the 20Global 20Environment http clojure org vars Vars 20and 20the 20Global
  • 如何在 Ubuntu 16 中下载 Appium 桌面

    我正在尝试在 Ubuntu 16 中下载 Appium Desktop 到目前为止我只是使用终端来运行它 据我所知 对于 Ubuntu 我必须下载他们在 git 上的源代码版本 源代码 tar gz 而不是他们的 exe windows 或
  • 在C中使用枚举类型变量作为字符串的简单方法?

    这就是我想做的 typedef enum ONE TWO THREE Numbers 我正在尝试编写一个函数来执行类似于以下内容的 switch case char num str 10 int process numbers str Nu
  • 为具有抽象复杂类型的模式生成类

    我正在使用一些定义抽象复杂类型的模式 例如
  • 所需类型与找到类型相同

    我想做这个 Foo
  • “Lato”字体在 Safari 中呈现奇怪,而不是在 Chrome 或 Firefox 中呈现

    我使用谷歌网络字体中的 Lato 字体 它在除 safari 之外的所有浏览器上显示良好 我用它font weight 100 以下是不同浏览器的一些屏幕截图 知道什么可能导致它变得非常薄吗 或者如果有办法我可以将其设置为渲染font we
  • 如何在Android中设置EditText的最小和最大字符限制?

    我想设置 EditText 框的最小和最大输入值 我正在为 EditText 创建一个简单的验证 它采用 A Z 和 0 9 值 最小 5 个字符 最大 8 个字符 我设置最大验证和其他验证如下
  • 通过不同的容器修改std容器的内容

    我不知道这是否是正确的方法 但我认为它解释了我想要实现的目标 我有三个向量 std vector