Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将一个constexpr数组初始化为其他两个constexpr数组的总和_C++_Arrays_C++11_Initialization_Initializer List - Fatal编程技术网

C++ 将一个constexpr数组初始化为其他两个constexpr数组的总和

C++ 将一个constexpr数组初始化为其他两个constexpr数组的总和,c++,arrays,c++11,initialization,initializer-list,C++,Arrays,C++11,Initialization,Initializer List,给定两个constepr数组(type[N]或std::array) 是否可以初始化执行元素操作(或constepr函数)的新constepr数组 例如,是否可以使用此代码 constexpr int sum(int i) { return A[i] + B[i]; } constexpr int S[5] { sum(0), sum(1), sum(2), sum(3), sum(4) }; 可以更方便地重写,为S中的每个元素调用sum(i)?类似的事情已经做了很多次,但这里有一个针对数组上

给定两个
constepr
数组(
type[N]
std::array

是否可以初始化执行元素操作(或
constepr
函数)的新
constepr
数组

例如,是否可以使用此代码

constexpr int sum(int i) { return A[i] + B[i]; }
constexpr int S[5] { sum(0), sum(1), sum(2), sum(3), sum(4) };

可以更方便地重写,为
S
中的每个元素调用
sum(i)

类似的事情已经做了很多次,但这里有一个针对数组上这种特殊编译时操作的解决方案;)


对于任意n元函数和任意类似数组的类型:

template<class F, class... Args>
constexpr auto index_invoke(F f, int i, Args&&... args)
-> decltype( f(args[i]...) )
{
    return f(args[i]...);
}

template<class F, int... Is, class... Args>
constexpr auto transform_impl(F f, seq<Is...>, Args&&... args)
-> std::array<decltype( f(args[0]...) ), sizeof...(Is)>
{
    return {{ index_invoke(f, Is, std::forward<Args>(args)...)... }};
}

template <class T, class...>
struct get_extent_helper
: std::integral_constant<int,
                         std::extent<typename std::remove_reference<T>::type>{}>
{};

template<class F, class... Args>
constexpr auto transform(F f, Args&&... args)
-> decltype( transform_impl(f, gen_seq< get_extent_helper<Args...>{} >{},
                            std::forward<Args>(args)...) )
{
    using N = get_extent_helper<Args...>;
    return transform_impl(f, gen_seq<N{}>{}, std::forward<Args>(args)...);
}
模板
constexpr自动索引_调用(F、int i、Args&…Args)
->decltype(f(args[i]…))
{
返回f(args[i]…);
}
模板
constexpr自动转换\u impl(F,seq,Args&…Args)
->std::数组
{
返回{index_invoke(f,Is,std::forward(args)…)};
}
模板
结构获取\u范围\u辅助对象
:std::积分常数
{};
模板
constexpr自动转换(F,Args&…Args)
->decltype(transform_impl(f,gen_seq{},
标准::转发(args)…)
{
使用N=get\u extent\u helper;
返回转换impl(f,gen_seq{},std::forward(args)…);
}
使用别名模板实现更轻量级:

template <class T, class...>
using get_extent_helper =
  std::integral_constant<int,
                         std::extent<typename std::remove_reference<T>::type>{}>;
模板
使用get\u extent\u帮助程序=
std::积分_常数;

但是这是g++4.8.1下的一个bug,看看吧。太棒了!我从这个答案中学到了很多,非常感谢!挑剔:
std::get
for
std::array
s@TomKnapen“从C++14开始,重载被标记为constexpr。”:(对于那些担心上述性能的人,我做了大量的测试来编译他的转换“任意二进制”使用lambda的for F与简单循环相比,在所有情况下,使用优化设置,在x86上创建的代码即使不完全相同,也是相似的。在大数组中,编译器生成循环函数,而在短数组中,它只是将两者展开。
template<class T, int N, class F, int... Is>
constexpr auto transform(T const (&lhs)[N], T const (&rhs)[N], F f,
                         seq<Is...>)
-> std::array<decltype( f(lhs[0], rhs[0]) ), N>
{
    return {{ f(lhs[Is], rhs[Is])... }};
}

template<class T, int N, class F>
constexpr auto transform(T const (&lhs)[N], T const (&rhs)[N], F f)
-> decltype( transform(lhs, rhs, f, gen_seq<N>{}) )
{
    return transform(lhs, rhs, f, gen_seq<N>{});
}

constexpr int sum(int l, int r) { return l+r; }
// ...
constexpr auto c = transform(a,b,sum);
template<class F, class... Args>
constexpr auto index_invoke(F f, int i, Args&&... args)
-> decltype( f(args[i]...) )
{
    return f(args[i]...);
}

template<class F, int... Is, class... Args>
constexpr auto transform_impl(F f, seq<Is...>, Args&&... args)
-> std::array<decltype( f(args[0]...) ), sizeof...(Is)>
{
    return {{ index_invoke(f, Is, std::forward<Args>(args)...)... }};
}

template <class T, class...>
struct get_extent_helper
: std::integral_constant<int,
                         std::extent<typename std::remove_reference<T>::type>{}>
{};

template<class F, class... Args>
constexpr auto transform(F f, Args&&... args)
-> decltype( transform_impl(f, gen_seq< get_extent_helper<Args...>{} >{},
                            std::forward<Args>(args)...) )
{
    using N = get_extent_helper<Args...>;
    return transform_impl(f, gen_seq<N{}>{}, std::forward<Args>(args)...);
}
template <class T, class...>
using get_extent_helper =
  std::integral_constant<int,
                         std::extent<typename std::remove_reference<T>::type>{}>;