编译时相当于 std::accumulate()

2023-11-26

我尝试编写一个基本的代码,编译时的版本std::accumulate()通过定义一个类模板,该模板将递归地迭代给定范围并在每次迭代时添加元素。

使用编译测试程序时gcc 4.8.4 on Ubuntu 14.04,我收到以下错误:

compile-time-accumulate.cpp: In function ‘int main()’:
compile-time-accumulate.cpp:44:40: error: call to non-constexpr function ‘std::vector<_Tp, _Alloc>::const_iterator std::vector<_Tp, _Alloc>::cbegin() const [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >; typename __gnu_cxx::__alloc_traits<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type>::const_pointer = const int*]’
                               v.cbegin(),
                                        ^
compile-time-accumulate.cpp:46:32: error: ‘class __gnu_cxx::__normal_iterator<const int*, std::vector<int> >’ is not a valid type for a template non-type parameter
                               0>::value;

这是代码:

Run it online

#include <iostream>
#include <vector>

template
<
    typename     ResultType,
    typename     IteratorType,
    IteratorType Iterator,
    int          RangeLength,
    ResultType   InitialValue
>
struct accumulator
{
    static_assert(RangeLength > 1, "The range length must be > 1");
    static constexpr ResultType value = InitialValue
                                      + accumulator<ResultType,
                                                    IteratorType,
                                                    Iterator + 1,
                                                    RangeLength - 1,
                                                    *Iterator>::value;
};

template
<
    typename     ResultType,
    typename     IteratorType,
    IteratorType Iterator,
    //int          RangeLength,
    ResultType   InitialValue
>
struct accumulator<ResultType, IteratorType, Iterator, 1, InitialValue>
{
    static constexpr ResultType value = InitialValue + *Iterator;
};


int main()
{
    std::vector<int> v = {4,5,6,7};

    const int a = accumulator<int,
                              decltype(v.cbegin()),
                              v.cbegin(),
                              4,
                              0>::value;

    std::cout << a << std::endl;
}

所以基本上,标准不允许在模板参数中使用变量,这就是我在这里所做的:

const int a = accumulator<int,
                          decltype(v.cbegin()),
                          v.cbegin(),
                          4,
                          0>::value;

Q:编码类模板(或任何其他“编译时”计算机制)以实现类似结果的正确方法是什么std::accumulate() ?

(理想情况下,人们应该能够像真实的那样传递自定义范围和二元运算std::accumulate())

EDIT: The std::vector代码中使用的只是一个示例。我也尝试过std::array和 C 风格的数组,但我仍然遇到类似的问题。

EDIT2:我不想使用宏。

EDIT3:我不想使用外部库。这里的目标是做一个简单的、独立的编译时计算堵塞。类模板是我的第一个想法,但我愿意接受其他建议/技术。


std::vector的存储是在运行时分配的。因此,在编译时不可能迭代 std::vector。

Now for std::array和原始数组。前提是你的std::array变量是一个constexpr您可以使用以下结构来累积它:

template<typename T, std::size_t N>
constexpr T compile_time_accumulator(std::array<T, N> const &A, int const i = 0) {
  return (i < N)? A[i] + compile_time_accumulator(A, i + 1) : T(0);
}

现场演示

对于原始数组,还必须声明它们constexpr,以下构造:

template<typename T, std::size_t N>
constexpr T compile_time_accumulator(T const (&A)[N], int const i = 0) {
  return (i < N)? A[i] + compile_time_accumulator(A, i + 1) : T(0);
}

现场演示

现在在 C++14 中关于constexpr更加放松,您可以执行以下操作:

template<typename T, std::size_t N>
constexpr T compile_time_accumulator(T const (&A)[N]) {
  T sum(T(0));

  for(int i = 0; i < N; ++i) {
    sum += A[i];
  }

  return sum;
}

现场演示

or

template<typename T, std::size_t N>
constexpr T compile_time_accumulator(std::array<T, N> const &A) {
  T sum(T(0));

  for(int i = 0; i < N; ++i) {
    sum += A[i];
  }

  return sum;
}

现场演示

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译时相当于 std::accumulate() 的相关文章

随机推荐

  • 从内存而不是磁盘向 CompilerParameters ReferencedAssemblies 提供程序集?

    我有一个CompilerParameters我用来喂食的物体Microsoft CSharp CSharpCodeProvider对象和一个ICodeCompiler从中派生出的对象 一切正常 我可以即时编译代码 我的问题是引用的程序集 现
  • 如何在 Google App Engine 上使用 Python 发送 JSON 格式的 cookie 数据?

    我正在尝试在 Python 脚本中编码一个对象并将其设置为 cookie 以便我可以使用客户端 JavaScript 读取它 我尝试的各种方法都遇到了问题 一般来说 cookie 的格式化方式会导致 JSON parse 中断 我当前的脚本
  • Angular 6“mat-button-toggle”不是已知元素

    我已经检查过这些问题 mat toolbar 不是已知元素 Angular 5 Jhipster md button 不是已知元素 模板解析错误 mat icon 不是已知元素 材质 2 md datepicker toggle 不是已知元
  • 将选定的文本复制到剪贴板而不使用 Flash - 必须是跨浏览器

    我想要一个按钮来选择文本textarea并将其复制到剪贴板 我似乎找不到任何适用于所有浏览器且不使用 Flash 的解决方案 这当然可行吗 我到处都见过它 但我猜他们使用闪光灯 如果可能的话我真的想远离它 因为有些人没有它 这就是我到目前为
  • grunt uglify 任务失败

    运行 grunt 时 出现以下错误 警告 无法写入 client dist js build js 文件 错误代码 未定义 使用 force 继续 我的 uglify 的配置Gruntfile js uglify build src cli
  • 有没有办法仅使用 CSS 生成给定范围内的随机数?

    例如 类似 div margin left random 100 100 目前无法在纯 CSS 中执行此操作 但是如果您使用 CSS 预处理器 例如LESS 那么您可以执行以下操作 randomMargin Math round Math
  • 隐式与显式链接到 DLL

    何时应隐式或显式链接到 DLL 常见做法或陷阱是什么 显式链接 DLL 的情况相当罕见 主要是因为它很痛苦并且容易出错 您需要为导出的函数编写函数指针声明 并正确获取 LoadLibrary GetProcAddress FreeLibra
  • 重新连接断开连接的 SignalR 客户端 (JS) 的最佳实践

    我想提高 signalR 客户端的客户端实现的弹性 目前 我这样做 hub server sendClientNotification string appSettings username 然而 偶尔会引发与连接相关的异常 因为服务器没有
  • 将纪元时间(毫秒)转换为日期时间

    我使用 ruby 脚本将 iso 时间戳转换为纪元 我正在解析的文件具有以下时间戳结构 2009 03 08T00 27 31 807 因为我想保留毫秒 所以我使用以下 ruby 代码将其转换为纪元时间 irb main 010 0 gt
  • JQuery Mobile - 用户登录最佳实践

    我正在使用 JQuery Mobile 为现有的 Web 应用程序构建一个移动界面 该应用程序需要用户身份验证 但我无法确定实现登录过程的最佳方法 我不太关心服务器端身份验证 而是如何在用户端实现它 经过一番尝试 似乎有以下选项 使用 PO
  • 如何在 Eclipse 启动配置中使用变量进行类路径定义?

    在我们的项目中 我们使用 Eclipse 启动配置 这些配置受版本控制 可与所有开发人员共享 现在需要将外部存档包含到启动配置文件的类路径中 幸运的是 所需的存档位于每个开发人员的本地 Maven 存储库中 我已经发现有一个名为的类路径变量
  • WPF 图像工具提示

    我在列表框内的图像上有一个工具提示 工具提示设置如下
  • 如何强制maven更新?

    我在另一台计算机上导入了已经工作的项目 它开始下载依赖项 显然我的互联网连接崩溃了 现在我得到以下信息 gt Build errors for comics org apache maven lifecycle LifecycleExecu
  • 无法加载目标的共享库“gdx”

    我遇到了同样的问题这个问题 但那里的答案并没有解决我的问题 我没有通过 gdxsetup jar 创建项目 我只是包含了 gdx jar 和 gdx backend android jar 我将 libgdx so 添加到 libs x86
  • 如何找出elasticsearch解析query_string的结果?

    有没有办法通过弹性搜索API如何查询字符串查询实际上被解析了吗 您可以通过查看手动执行此操作lucene查询语法 但是如果您可以查看解析器实际结果的一些表示 那就太好了 正如 javaanna 在评论中提到的那样 证实API 以下是我的本地
  • 在 pandas groupby 之后对每个组进行采样

    groupby操作后如何对每个组进行采样 import pandas as pd df pd DataFrame a 1 2 3 4 5 6 7 b 1 1 1 0 0 0 0 grouped df groupby b 鉴于上述设置 我想从
  • 用于在 Stackoverflow 上执行类似于“相关问题”的搜索的 SQL 是什么

    我正在尝试实现一个类似于 Stackoverflow 上的 相关问题 的功能 如何编写 SQL 语句来搜索数据库的 标题 和 摘要 字段中的类似问题 如果我的问题是 用于执行类似于 Stackoverflow 上的 相关问题 的搜索的 SQ
  • 如何强制我的 lambda 表达式尽早求值?修复 lambda 表达式的怪异问题?

    我编写了以下 C 代码 locationsByRegion new Dictionary
  • ggplot 条形图中的恒定宽度

    如何使用以下方法使多个条形图的条形宽度和条形之间的间距固定ggplot 每个图上有不同数量的条形 这是一次失败的尝试 m lt data frame x 1 10 y runif 10 ggplot m aes x y geom bar s
  • 编译时相当于 std::accumulate()

    我尝试编写一个基本的代码 编译时的版本std accumulate 通过定义一个类模板 该模板将递归地迭代给定范围并在每次迭代时添加元素 使用编译测试程序时gcc 4 8 4 on Ubuntu 14 04 我收到以下错误 compile