gpt4 book ai didi

c++ - 如何将单个对象转换为boost::any_range?

转载 作者:行者123 更新时间:2023-12-03 07:37:21 24 4
gpt4 key购买 nike

我正在尝试创建并返回仅包含一个对象的boost:any_range(我不知道这是否是核心问题),但是出现以下错误:

  • 错误C2893:无法专门化功能模板
    'range_iterator ::type boost::range_adl_barrier::begin(T&)'
  • 注意:具有以下模板参数:
  • 注意:'T = const WrappedRange'
  • 错误C2672:'end':找不到匹配的重载函数
  • 错误C2893:无法专门化功能模板
    'range_iterator ::type boost::range_adl_barrier::end(T&)'
  • 注意:具有以下模板参数:note:'T = const
    WrappedRange'

  • 您可以在下面找到相关的代码片段:
  • 这是我要调用的函数,在编译期间失败:
  • const HandleRange BasicCollection::GetPartHandles() const
    {
    return HandleRange
    //return -> also tried this
    {
    Handle(GenericHandleManager::CreatePartHandleValue(GenericHandleManager::GetPartIdx(_collectionHandle)))
    };
    }

    以某种方式可以正常工作,但这并不是很干净:
    const HandleRange BasicCollection::GetPartHandles() const
    {
    auto container = { _collectionHandle };

    return container | boost::adaptors::transformed([collectionHandle = _collectionHandle](const auto & index_value)
    {
    return HandleRange::value_type
    {
    Handle(GenericHandleManager::CreatePartHandleValue(GenericHandleManager::GetPartIdx(collectionHandle)))
    };
    });
    }
  • 这是应返回的HandleRange类型:
  • /**
    * Defines an alias representing a boost range for handles.
    */
    using HandleRange = boost::any_range<Handle, boost::forward_traversal_tag, const Handle>;
  • 使用的Handle对象:
  • class Handle
    {
    public:
    /**
    * Construct a handle from a handle value.
    * @param value The handle's value.
    */
    inline explicit Handle(int_fast64_t value) noexcept : _value(value)
    {
    }
    ...
    }
    感谢您的任何建议!

    最佳答案

    Somehow this works, but that's not really clean


    没有诊断程序就不能编译,因为 auto被推导为 std::initializer_list<Handle>
    该方法调用 Undefined Behaviour,因为返回后初始化列表不存在。
    解决方案 any_range应该能够返回迭代器范围。
    指针是迭代器。
    任何单个对象 o都可以视为范围 [&o, &o + 1)。这是有效的迭代器范围。
    如果 GenericHandleManager::CreatePartHandleValue(...)返回引用,则将这些结合起来已经是解决方案 :
    const HandleRange BasicCollection::GetPartHandles() const {
    Handle& h =
    GenericHandleManager::CreatePartHandleValue(
    GenericHandleManager::GetPartIdx(_collectionHandle));
    return boost::make_iterator_range(&h, &h + 1));
    }
    单例山脉
    但是,如果它返回一个临时值,则需要设置“范围”:
    template <typename T>
    struct SingletonRange : boost::iterator_range<T*> {
    T val;
    SingletonRange(T val)
    : boost::iterator_range<T*>(std::addressof(val), std::addressof(val) + 1),
    val(std::move(val))
    { }
    };
    现在,您可以放心地写了(即使CreatePartHandleValue返回了一个临时值):
    HandleRange BasicCollection::GetPartHandles() const {
    Handle h =
    GenericHandleManager::CreatePartHandleValue(
    GenericHandleManager::GetPartIdx(_collectionHandle));

    return SingletonRange<Handle> {h};
    }
    完整演示
    Live On Coliru
    #include <boost/range/iterator_range.hpp>

    template <typename T>
    struct SingletonRange : boost::iterator_range<T*> {
    T val;
    SingletonRange(T val)
    : boost::iterator_range<T*>(std::addressof(val), std::addressof(val) + 1),
    val(std::move(val))
    { }
    };

    struct Handle{};
    struct GenericHandleManager {
    static int GetPartIdx(Handle) { return 42; }
    static Handle CreatePartHandleValue(int) { return {}; }
    };

    #include <boost/range/any_range.hpp>
    using HandleRange = boost::any_range<Handle, boost::forward_traversal_tag, const Handle>;

    struct BasicCollection {
    HandleRange GetPartHandles() const;
    private:
    Handle _collectionHandle;
    };

    HandleRange BasicCollection::GetPartHandles() const {
    Handle h =
    GenericHandleManager::CreatePartHandleValue(
    GenericHandleManager::GetPartIdx(_collectionHandle));

    return SingletonRange<Handle> {h};
    }

    #include <iostream>
    int main() {
    BasicCollection coll;
    for (Handle h : coll.GetPartHandles()) {
    std::cout << "Handle in loop\n";

    boost::ignore_unused_variable_warning(h);
    }
    }

    Keep in mind that copying that range is as expensive as copying aniterator_range<Handle*> plus copying the Handle itself. I'massuming the Handle is lightweight (as usual for handles)


    版画
    Handle in loop

    ¹只要您确定在该范围的生命周期内不使用SingletonRange中的任何迭代器即可。虽然这是一种常见的C++模式

    关于c++ - 如何将单个对象转换为boost::any_range?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65238116/

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