C++ 如何将单个对象转换为boost::任意范围?
我试图创建并返回一个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
- 错误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)))
};
});
}
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