“天真”的解决方案是;
std::vector<T> vector_of_objects;
vector_of_objects.reserve(vector_of_pointers.size());
for (T const * p : vector_of_pointers)
vector_of_objects.push_back(*p);
上述内容似乎很麻烦,也许并不是很明显。
是否有一种解决方案至少效率不高,可能更快更直观?我认为C ++ 11可能有一个我不知道的解决方案......
答案 0 :(得分:8)
在我看来,这两行更短更易读:
for (auto p : vector_of_pointers)
vector_of_objects.emplace_back(*p);
函数std::for_each
并不比基于范围的循环短,有时因为传递lambda表达式而变得更大。
函数std::transform
甚至比std::for_each
更长,但 transform 这个词有助于找出以下内容。
答案 1 :(得分:2)
你正在做正确的方法。另一种方法是使用内置算法库,如下所示:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
// Create a vector of pointers
std::vector<int*> vptr;
vptr.push_back(new int(1));
vptr.push_back(new int(2));
// Copy to vector of objects
std::vector<int> vobj;
std::for_each(vptr.begin(), vptr.end(), [&](int *n) { vobj.emplace_back(*n); });
// Free the pointers
std::for_each(vptr.begin(), vptr.end(), [&](int *n) { delete n; });
// Print out the vector of objects
std::copy(vobj.begin(), vobj.end(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}
答案 2 :(得分:2)
习惯的方式是使用std::transform
:
std::transform( vector_of_pointers.begin(),
vector_of_pointers.end(),
std::back_inserter( vector_of_objects ),
[]( T* p ) { return *p; } );
这是否比你写的“更好”是另一个 问题:它具有惯用性和优势的优点 实际上命名正在发生的事情(这使得代码略有不同 更清晰)。另一方面,“转型”非常非常 简单,所以它很容易在循环中识别,并且 编写这样的循环的新形式使得事情相当清楚 好。
答案 3 :(得分:1)
不,你必须在你的解决方案中调用copy-ctor,没有办法解决这个问题。
答案 4 :(得分:0)
std::vector<T*> vecPointers;
std::vector<T> vecValues;
for(size_t x=0;x<vecPointers.size();x++)
{
vecValues.push_back(*vecPointers[x]);
}
我相信如果类型T是自定义对象,那么您需要为类T创建一个复制构造函数。
class T
{
private:
int someValue;
public:
T()
{
}
T(const T &o)// copy constructor
{
someValue = o.someValue;
}
virtual ~T()
{
}
};
答案 5 :(得分:0)
在我看来,真正的问题是你是否经常这样做,因为值得在一个地方编写额外的代码来清理其他地方的代码。
我可以想象写一个允许你这样做的deref_iterator
:
std::vector<T> vector_of_objects{
deref_iterator(std::begin(vector_of_pointers)),
deref_iterator(std::end(vector_of_pointers))};
现在,我们留下的问题是这是否真的比原始循环短。就简单的击键次数而言,它可能取决于你给出的名字。如果您不关心可读名称,可能是:
vector<T> v_o{d(begin(v_p)), d(end(v_p))};
简短的名字显然会让它变短,但我当然不会建议他们 - 如果我还没有输入,我就不知道这个世界是什么意思。较长的名称(需要重复几次)显然会增加更多的击键,但我无法想象有人认为可读性不值得。
无论如何,deref_iterator
本身显然会占用一些代码。迭代器有足够的锅炉板,通常需要大约100行代码。让我们(有点随意)决定每次使用它时都会保存一行代码。在此基础上,你必须使用它100次才能收支平衡。
我不确定在整体代码的表征方面是否准确 - 迭代器的代码主要是锅炉,除了错字之外,没有太多可能真的出错。在大多数情况下,它应该包括正确的标题,并使用它,而不是几乎不必查看迭代器本身的代码。
在这种情况下,即使总代码行数增加,我也可以接受它作为改进。写它只使用一次显然是一种损失,但我不认为它需要完全100次才有资格作为收支平衡。