C++ 如何将单个对象转换为boost::任意范围?

C++ 如何将单个对象转换为boost::任意范围?,c++,boost,compiler-errors,boost-range,boost-iterators,C++,Boost,Compiler Errors,Boost Range,Boost Iterators,我试图创建并返回一个boost:任何只包含一个对象的_范围(我不知道这是否是核心问题),但我得到以下错误: 错误C2893:未能专门化函数模板 'range\u iterator::type boost::range\u adl\u barrier::begin(T&)' 注意:使用以下模板参数: 注:“T=const WrappedRange” 错误C2672:“结束”:未找到匹配的重载函数 错误C2893:未能专门化函数模板 'range\u iterator::type boost::r

我试图创建并返回一个boost:任何只包含一个对象的_范围(我不知道这是否是核心问题),但我得到以下错误:

  • 错误C2893:未能专门化函数模板 'range\u iterator::type boost::range\u adl\u barrier::begin(T&)'
  • 注意:使用以下模板参数:
  • 注:“T=const WrappedRange”
  • 错误C2672:“结束”:未找到匹配的重载函数
  • 错误C2893:未能专门化函数模板
    'range\u iterator::type boost::range\u adl\u barrier::end(T&)'
  • 注意:使用以下模板参数:注意:'T=const
    WrappedRange'
您可以在下面找到相关的代码段:

  • 这是我要调用的函数,在编译过程中失败:
  • 不知怎的,这是可行的,但这并不干净:

    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类型:
  • 谢谢你的建议

    不知何故,这是可行的,但这不是真正的清洁

    没有诊断就不能编译,因为
    auto
    被推断为
    std::initializer\u list

    该方法调用,因为返回后初始值设定项列表不存在

    解决
    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));
    }
    
    单态范围 但是,如果它返回临时值,则需要将其设置为“范围”:

    完整演示

    #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);
        }
    }
    

    < P> >只要您确保在该范围的生存期之后不使用单级范围内的任何迭代器。这是一个常见的C++模式,尽管

    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)
          {
          }
    ...
    }
    
    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))
        { }
    };
    
    HandleRange BasicCollection::GetPartHandles() const {
        Handle h =
            GenericHandleManager::CreatePartHandleValue(
                GenericHandleManager::GetPartIdx(_collectionHandle));
    
        return SingletonRange<Handle> {h};
    }
    
    #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);
        }
    }
    
    Handle in loop