C++ 可观察容器

C++ 可观察容器,c++,c++11,C++,C++11,我经常遇到需要从数据源创建选择、操作选择并将更改反馈给原始数据源的情况。差不多 #include <vector> void manipulate(std::vector<int> &vector) { // Manipulate vector... } int main() { // Data source std::vector<int> dataSource{1, 2, 3, 4}; // Select ev

我经常遇到需要从数据源创建选择、操作选择并将更改反馈给原始数据源的情况。差不多

#include <vector>

void manipulate(std::vector<int> &vector) {
    // Manipulate vector...
}

int main() {
    // Data source
    std::vector<int> dataSource{1, 2, 3, 4};

    // Select every second entry
    std::vector<int> selection{v[0], v[2]};

    // Manipulate selection
    manipulate(selection);

    // Feed data back to the data source
    dataSource[0] = selection[0];
    dataSource[2] = selection[1];

    return 0;
}

为了将数据反馈回数据源的过程自动化,我可以使用std::reference_包装器将选择更改为指针或引用向量,并将其传递给操作其参数的函数。或者,我可以创建一个类ObservableVector,它将数据源作为成员保存,并将对其所做的所有更改传播到数据源。但是,在这两种情况下,我都需要更改maniple的签名,以接受指针向量或observector。我是否有可能保留原始的操纵函数而不需要创建包装函数,并且仍然自动将数据反馈回原始源?

您可以将逻辑包装到函数中,例如:

template <typename T, typename F>
void manipulate_selection(std::vector<T>& v,
                          F f,
                          const std::vector<std::size_t>& indexes)
{
    std::vector<T> selection;

    // Select every second entry
    selection.reserve(indexes.size());
    for (auto index : indexes) {
        selection.pusk_back(v[index]);
    }

    // Manipulate selection
    f(selection);

    // Feed data back to the data source
    for (std::size_t i = 0; i != indexes.size(); ++i) {
        v[indexes[i]] = selection[i];
    }
}
查看范围库,例如。可以从容器创建一个范围,以包含容器的子集,例如,每个第n个元素,或者一个包含与谓词对象匹配的所有元素的范围。这样,就很容易组合复杂的操作。下面是一些示例代码,它迭代容器的每一个第二个元素,对其进行过滤,然后计算一些内容

using namespace boost::adaptors;
using namespace boost;

// assume we have a predicate int -> bool
bool pred(int x);

// some function which transforms each element
int computation(int);

std::vector<int> elements = // ...

auto everySecondElement = elements | strided(2);
auto filtered = everySecondElement | filtered(pred);

transform( filtered, filtered.begin(), computation);

这更像是一种函数编程风格,它使范围处理的组合变得非常简单和富有表现力。它可能需要对操作函数进行更改,但我认为使用范围库可以大大提高C++代码。

您的选择向量不存储选定元素的原始位置。你需要把它们存放在别处。也许在索引的并行向量中,或者为了更一般性,在迭代器中。您可以创建一个选择类,将选定图元及其位置存储在单独的容器中。
using namespace boost::adaptors;
using namespace boost;

// assume we have a predicate int -> bool
bool pred(int x);

// some function which transforms each element
int computation(int);

std::vector<int> elements = // ...

auto everySecondElement = elements | strided(2);
auto filtered = everySecondElement | filtered(pred);

transform( filtered, filtered.begin(), computation);