最快的方式 std::vector<Derived> to std::vector<Base>
Fastest Way To std::vector<Derived> to std::vector<Base>
这是测试代码:
class A{};
class B : public A{};
void Test(const std::vector<A>& a)
{
}
int main()
{
std::vector<A> a;
std::vector<B> b;
Test(a);
Test(b);//Compiler Error
return 0;
}
由于std::vector<A>
和std::vector<B>
是不同类型的,因此我们无法从一种转换为另一种。
可选方式可以是:
class A{};
class B : public A{};
void Test(const std::vector<A>& a)
{
}
int main()
{
std::vector<A> a;
std::vector<B> b;
Test(a);
Test(std::vector<A>(b.begin(), b.end()));
return 0;
}
它起作用,但需要从B
到A
进行额外的复制。如果A
或B
是一个大对象,则可能会非常慢。更好的选择是:
class A{};
class B : public A{};
void Test(const std::vector<A>& a)
{
}
int main()
{
std::vector<A> a;
std::vector<B> b;
Test(a);
Test(std::vector<A>(std::make_move_iterator(b.begin()), std::make_move_iterator(b.end())));
return 0;
}
由于它只是移动迭代器而不是整个B
类,因此需要更好的性能。但是有一些额外的成本 - 如果b
是一个非常大的向量,有大量的项目,迭代也会减慢我的代码速度。
所以我想知道是否有办法直接将std::vector<B>
转换为std::vector<A>
而无需任何额外费用?
一种方法是使向量成为 Test 函数的模板参数。调用代码将保持不变,无需复制。
#include <vector>
#include <iostream>
class A{
public:
virtual void print() const {
std::cout << "A" << std::endl;
}
};
class B : public A{
virtual void print() const {
std::cout << "B" << std::endl;
}
};
template <typename ContainerA>
void Test(const ContainerA& aas)
{
for(const A& a:aas) {
a.print();
}
}
int main()
{
std::vector<A> a;
a.push_back(A());
std::vector<B> b;
b.push_back(B());
Test(a);
Test(b);
return 0;
}
我不知道
它是否对您有用,但我能想到的最好的方法是将std::vector<Derived>
传递给函数并将元素迭代为Base
元素。
类似的东西
template <typename D>
void Test (std::vector<D> const & v)
{
for ( A const & elem : v )
{
// use elem
}
}
使用 SFINAE,您只能对Base
或从Base
元素派生的向量启用Test()
,如下所示
template <typename D>
typename std::enable_if<std::is_base_of<A, D>::value>::type
Test (std::vector<D> const & v)
{
for ( A const & elem : v )
{
// use elem
}
}
所以你有
int main ()
{
std::vector<A> a;
std::vector<B> b;
std::vector<int> c;
Test(a); // compile
Test(b); // compile
// Test(c); // compiler error
}
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中