gpt4 book ai didi

c++ - boost 收集范围的适配器

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:07:33 25 4
gpt4 key购买 nike

我想编写一个 boost 适配器放在适配器链的末尾以创建一个集合,如下所示:

set<string> s = input | filtered(...) | transformed(...) | to_set;

使用 Method 3.1我写了下面的代码,它似乎按预期工作:

namespace detail
{
struct to_set_forwarder
{
};
};

template <class R> inline auto operator|(R& r, detail::to_set_forwarder)
{
return set<R::value_type>(r.begin(), r.end());
}

template <class R> inline auto operator|(const R& r, detail::to_set_forwarder)
{
return set<const R::value_type>(r.begin(), r.end());
}

namespace
{
const auto to_set = detail::to_set_forwarder();
}

void F()
{
vector<string> input{ "1", "2", "3" };
auto result = input
//| boost::adaptors::filtered([](const auto& _) { return true; })
| to_set;
}

但是如果我取消注释那一行,我会得到:

error C2338: The C++ Standard forbids containers of const elements because allocator is ill-formed.

如果我将 operator| 的第一个参数设置为 && 那么直到我取消注释 filtered() 行,然后我得到:

error C2825: 'R': must be a class or namespace when followed by '::'

正确的做法是什么?

最佳答案

就像它说的,标准容器不能存储 const 元素。您也不想这样做(因为无论如何您都会存储拷贝。如果您希望它们为常量,则可以使容器 const)。

修复是:

template <class R> inline auto operator|(const R& r, detail::to_set_forwarder)
{
return std::set<typename R::value_type>(r.begin(), r.end());
}

(删除 const)。

Live On Coliru

#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <set>
#include <vector>
#include <iostream>
#include <string>

namespace detail
{
struct to_set_forwarder
{
};
}

template <class R> inline auto operator|(R& r, detail::to_set_forwarder)
{
return std::set<typename R::value_type>(r.begin(), r.end());
}

template <class R> inline auto operator|(const R& r, detail::to_set_forwarder)
{
return std::set<typename R::value_type>(r.begin(), r.end());
}

namespace
{
const auto to_set = detail::to_set_forwarder();
}

void F()
{
std::vector<std::string> input{ "1", "2", "3", "2" };
auto result = input
| boost::adaptors::filtered([](const auto& _) { return true; })
| to_set;

for (auto x : result)
std::cout << x << " ";
}

int main() {
F();
}

打印

1 2 3

PS:您缺少 typename 资格(有时尝试其他编译器而不是 MSVC)

PS:你可以boost::copy_range:

auto result = boost::copy_range<std::set<std::string> >(input
| boost::adaptors::filtered([](const auto& _) { return true; })
);

关于c++ - boost 收集范围的适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44772765/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com