如果我有一个数组,如:
struct S {... };
S m_aArr[256];
我希望用它来构造一个矢量,例如:
std::vector<S*> m_vecS;
无论如何都要这样做而不是循环并推回&m_aArr[i]
?
我知道我不能使用在数组上使用std::begin
和std::end
的传统方法,因为向量是指针之一,原始数组是对象之一,所以我们不能只传入一个块记忆。
答案 0 :(得分:12)
您可以使用标准库进行迭代并向您推送:
std::transform(std::begin(m_aArr), std::end(m_aArr),
std::back_inserter(m_vecS), std::addressof<S>);
这将通过将std::addressof<S>
函数应用于m_aArr
来转换push_back
中的每个元素。然后,std::back_inserter
迭代器将每个转换后的元素m_vecS
编辑到std::begin
。
要在C ++ 11之前执行此操作,您将无法访问std::end
,std::addressof
或std::transform(m_aArr, m_aArr + 256, std::back_inserter(m_vecS), boost::addressof<S>);
,因此它看起来更像是:
{{1}}
这使用boost::addressof
。
答案 1 :(得分:5)
你可以让std::transform
执行循环:
transform(std::begin(a), std::end(a), std::back_inserter(v),
[] (S& s) { return &s; });
请注意,您无需完全限定名称std::transform
,因为函数名称将由ADL找到。
这是一个测试其行为的完整程序:
#include <iostream>
#include <vector>
#include <algorithm> // <== Required for std::transform
#include <iterator> // <== Required for std::back_inserter, std::begin, std::end
struct S
{
S() : i(0) { }
S(int i_) : i(i_) { }
int i;
};
int main()
{
S a[256] = { 42 }; // Copy-initializes first element from 42,
// default-constructs all other elements
std::vector<S*> v;
transform(std::begin(a), std::end(a), std::back_inserter(v),
[] (S& s) { return &s; });
std::cout << v.size() << std::endl; // Prints 256
std::cout << v[0]->i << std::endl; // Prints 42
std::cout << v[1]->i << std::endl; // Prints 0
}
这是一个live example。
答案 2 :(得分:1)
使用std::generate_n()
的解决方案执行std::vector
的单一分配,而不是通过std::vector::push_back()
执行多次分配:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
struct S {};
S a[128];
S* ap = a;
std::vector<S*> v(sizeof(a)/sizeof(a[0]));
std::generate_n(std::begin(v), v.size(), [&]() { return ap++; });
for (size_t i = 0; i < v.size(); i++)
{
if (&a[i] != v[i]) // Ensure same address at each element.
{
std::cerr << "Error\n";
break;
}
}
return 0;
}
在http://ideone.com/73nKST在线查看。