我遇到这种情况:
class A {
...
};
class B {
public:
B(A x) { .... }
}
std::array<A, some_constant_value> init;
std::array<B, some_constant_value> arr = {
init[0],
init[1],
init[2],
...... ,
init[some_constant_value-1]
};
有没有比这更好的语法,以避免键入所有元素? (并且这不需要干预some_constant_value会改变的可能性吗?)
答案 0 :(得分:4)
我有这个代码。我想这就是你想要的:
template<unsigned... Indices>
struct indices {
using next = indices<Indices..., sizeof...(Indices)>;
};
template<unsigned N>
struct build_indices {
using type = typename build_indices<N-1>::type::next;
};
template<>
struct build_indices<0> {
using type = indices<>;
};
namespace impl {
template<typename To, typename From, unsigned... Is>
std::array<To, sizeof...(Is)>
array_convert_impl(std::array<From, sizeof...(Is)> const& from, indices<Is...>) {
return std::array<To, sizeof...(Is)>{{ from[Is]... }};
}
} // namespace impl
template<typename To, typename From, unsigned N>
std::array<To, N>
array_convert(std::array<From, N> const& from) {
return impl::array_convert_impl<To>(from, typename build_indices<N>::type());
}
然后你可以这样做:
std::array<B, some_constant_value> arr = array_convert<B>(init);
答案 1 :(得分:1)
标准库提供的替代解决方案是:
std::array<B, some_constant_value>
arr((std::copy(init.begin(),init.end(),(&arr)->begin()),arr));
请注意,构造函数的参数由((...))
括起来,以便它
被正确解析为逗号表达式而不是两个参数。
此解决方案依赖于B
可隐式构造的事实
A
。一个简短的解决方案,如果转换构造函数也是有效的
明确的是:
auto lamb =
[&init]() -> B { static size_t i = 0; return B(init[i++]); };
std::array<B, some_constant_value>
arr((std::generate((&arr)->begin(),(&arr)->end(),lamb),arr));
以下测试程序,使用GCC 4.7.2,clang 3.2和Intel C ++ 13.1.1构建,
(选项-g -O0 -Wall -std=c++11
)说明了两种解决方案:
#include <iostream>
#include <array>
#include <algorithm>
struct A
{
int _i = 42;
};
struct B
{
B(A x)
: _i(x._i){}
int _i;
};
struct C
{
explicit C(A x)
: _i(x._i){}
int _i;
};
using namespace std;
int main()
{
array<A, 10> init;
array<B, 10> arr((copy(init.begin(),init.end(),(&arr)->begin()),arr));
cout << "arr contains..." << endl;
for (size_t i = 0; i < arr.size(); ++i) {
cout << arr[i]._i << endl;
}
auto lamb =
[&init]() -> C { static size_t i = 0; return C(init[i++]); };
array<C, 10> brr((generate((&brr)->begin(),(&brr)->end(),lamb),brr));
cout << "brr contains..." << endl;
for (size_t i = 0; i < brr.size(); ++i) {
cout << brr[i]._i << endl;
}
return 0;
}