从对象创建矢量包装器,该对象只允许使用索引访问向量
Creation of a vector wrapper from an object which only allows accessing vector with index
我创建了一个用于使用可链过滤器和映射操作的类,主要用于避免循环冗余。
例如
std::vector<ObjectASharedPtr> temp = GetListOfA();
FunctionalIteratableWrapper<ObjectASharedPtr> wrapper( temp );
wrapper.Filter([]( ObjectASharedPtr objA ){ return objA->isApple(); } ).Map([]( ObjectASharedPtr objA ){ return objA->Bite(); })
我的班级的简短版本可以在问题的底部看到,以免用长长的代码破坏问题。
当我将矢量作为" std :: vector"获得时,它的功能非常完美。我可以轻松地启动包装纸。
,但是现在有一个旧代码,它不会直接将数据作为列表,而是使用索引:
auto count = LegacyObjList->getCount();
for ( int i = 0; i < count; i++ )
LegacyObj.getObjByIndex(i);
当前我想用这种结构实例化我的functionalatableWrapper,该结构只允许使用索引访问我需要执行:
std::vector<LegacyObj> tempVec;
auto count = LegacyObjList->getCount();
for ( int i = 0; i < count; i++ )
tempVec.push_back(LegacyObj.getObjByIndex(i));
FunctionalIteratableWrapper<LegacyObj> wrapper(temp);
我想避免使用此循环,我现在每次都使用此对象创建包装器,该对象只允许使用索引访问。最好的解决方案应该是什么?
template< typename Value >
class FunctionalIteratableWrapper
{
public:
/*!
* brief A copy ctor like ctor. Which initiates this struct directly from vector of Iteratable.
* param list vector of Iteratable
*/
FunctionalIteratableWrapper( const std::vector<Value>& list )
{
iteratableList = list;
}
/*!
* brief Default ctor
*/
FunctionalIteratableWrapper()
{
}
template <typename F>
FunctionalIteratableWrapper& Filter( F filterFunction, bool isReturnOneElement = false )
{
std::vector<Value> newList;
for ( size_t i = 0; i < iteratableList.size(); i++)
{
if ( filterFunction(iteratableList[i]) )
{
newList.push_back(iteratableList[i]);
if ( isReturnOneElement )
break;
}
}
iteratableList = newList;
return *this;
}
,
template < typename T, typename F >
T Find( F filterFunction)
{
for ( size_t i = 0; i < iteratableList.size(); i++)
{
if ( filterFunction(iteratableList[i]) )
return Cast<typename T::element_type>(iteratableList[i]);
}
return T();
}
template <typename T, typename F>
FunctionalIteratableWrapper& Map( F applyFunction)
{
for ( size_t i = 0; i < iteratableList.size(); i++)
{
auto castedTerrain = Cast<typename T::element_type>(iteratableList[i]);
if ( castedTerrain )
applyFunction(castedTerrain);
}
return *this;
}
void Append( Value newElement )
{
iteratableList.push_back( newElement );
}
std::vector<Value> iteratableList;
};
处理此操作的简单方法是编写ADL辅助功能。
首先更改构造函数:
FunctionalIteratableWrapper( std::vector<Value> list ):
iterableList(std::move(list))
{
}
我们现在支持便宜的搬入。
接下来,创建一个名称空间:
namespace my_utility {
namespace helper1 {
template<class T, class A>
std::vector<T, A> to_vector( std::vector<T, A> in ) {
return std::move(in);
}
}
namespace helper2 {
using ::my_utility::helper1::to_vector;
template<class T>
auto as_vector( T&& t )
-> decltype( to_vector( std::forward<T>(t) ) )
{
return to_vector( std::forward<T>(t) );
}
}
using ::my_utility::helper2::as_vector;
}
现在调用::my_utility::as_vector(x)
在to_vector(x)
上进行ADL查找。如果找不到它,它试图将x
推断为std::vector<T,A>
并返回副本。
现在我们添加了一个构造函数:
template<class T,
class=std::enable_if_t< !std::is_same< std::decay_t<T>, FunctionalIteratableWrapper >::value >
>
FunctionalIteratableWrapper( T&& t ):
iterableList(::my_utility::as_vector(std::forward<T>(t))
{
}
我们几乎在那里!
在LegacyObj
的命名空间中,写下:
std::vector<LegacyObj> to_vector( LegacyObjList const* pList ) {
if (!pList _obj) return {};
std::vector<LegacyObj> retval;
int size = pList->getCount();
retval.reserve(size);
for (int i = 0; i < size; ++i)
retval.push_back(pList->getObjByIndex(i);
return retval;
}
,它将由as_vector
神奇地找到(嗯,使用ADL)。
现在可以将LegacyObjList const*
隐式转换为您的FunctionalInterableWrapper
。
未测试的代码。您可以首先编写to_vector
,然后手动测试并获得99%的方式。
然后执行::my_utility::as_vector
技巧。
最后,查看您是否可以获取调用as_vector
工作的构造函数。
每个添加值,并且可以与其他值分开写。
相关文章:
- 在CToolBar对象中使用PNG时出现问题
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 将 exprtk 与自定义类的对象一起使用
- 如何将来自 Boost.Python 的map_indexing_suite与自定义而不是标准对象一起使用?
- 是否有正确的方法对生成文件中的对象文件使用模板命令?(C++)
- 正确构造和销毁 Setter 依赖注入对象(可能使用 qt)
- 2 个 COM 对象,并在另一个对象中使用其中一个对象的接口
- 将指向类对象的智能指针与类对象混合使用
- 为什么我可以在临时 std::ofstream 对象上使用"operator<<"?
- 如何将任何值转换为对象并使用 boost::p roperty_tree json 添加成员
- 有没有办法在两个共享对象之间使用相同的全局变量?
- 将 OpenGL 实例化图形与移动对象一起使用
- 我是否要创建一个对象来使用C 中的类方法
- 继承的类对象如何使用私有数据成员
- 使用动态指针数组进行动态对象分配 - 使用什么删除?
- 如何使用 new 和 delete 与 OpenGL 的缓冲区对象一起使用?
- 当删除部分依赖列表时,GNU make 对每个对象文件使用相同的源文件
- 在原始对象上使用惯用(例如 TBB 的 thread_enumerable_specific')移动赋值调用析构函数
- 让 SFINAE 在重载的函数对象上使用"is_callable"
- 如何将指针与对象一起使用;构造函数和破坏者.C