问题标签 [expression-templates]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
7292 浏览

c++ - 使用比较运算符时检查多个值

我一直认为对于任何比较语句,即X == YorX != Y是格式,并且您将语句与&&or链接在一起||

没有什么方法可以X == (Y || Z)代替X == Y || X == Z吗?

编辑:既然已经确定这是不可能干净地做到的,那还能怎么做呢?

0 投票
1 回答
663 浏览

c++ - 英特尔 C++ 编译器无法处理深度模板?

我有一个使用marray库的 C++ 项目。目前,它可以在 Windows 7 x64 上使用 MinGW g++ 4.7 和 msvc2010 以及在 Linux Mint x64 上使用 g++ 4.7 进行编译和运行。我决定尝试一下适用于 Linux 的 Intel C++ compiler v. 12.1.4。它能够编译代码,但是当它尝试执行任何干扰表达式模板的行时(如 c = a + b 其中所有三个项都是矩阵),它会因分段错误而崩溃。此问题会影响应用程序的调试和发布版本。

我还尝试为 marray 库编译单元测试和教程代码,英特尔 C++ 编译代码但如果它有任何表达式模板则无法运行它。英特尔 C++ 是否真的与深度模板一样糟糕,还是我遗漏了什么?我是否需要设置任何特殊的编译器标志才能使模板表达式起作用?或者也许只是我正在使用的特定库有问题,而不是一般的表达式模板技术?

我还尝试在 n 上使用各种各样的 -ftemplate-depth- n 标志设置10 ^ 10的大得可笑的值,并且在没有分段错误的情况下运行我的应用程序和 marray 单元测试/教程仍然没有运气。

更新:这是来自上述库的教程-marray 的 gdb 日志,该库在调试模式下使用 icpc 编译。

看起来问题一般不是源于表达式模板技术,数字数组算术工作正常。当我尝试将一个数组添加到另一个数组时,就会出现问题。

更新。2:实际上整个事情看起来很像这里提到的问题。解决方案应该是重写 operator E&() { return static_cast(*this); } 变成类似 E& get_ref() { return static_cast(*this); 和 const 引用相同。当然,在代码中改变这些东西的用法。我会尽快尝试并报告结果。

0 投票
2 回答
12419 浏览

c++ - 表达式模板和 C++11

让我们看一下表达式模板的一个特殊好处:ET 可用于避免内存中出现在重载运算符中的向量大小的临时变量,例如:

在 C++11 中,此函数的 return 语句应用移动语义。没有向量的副本。那是一场胜利。

但是,如果我看一个简单的表达式,例如

我看到上面的函数被调用了两次(对于两者operator+),而最终的分配可以通过移动语义完成。

总共执行了 2 个循环。意味着我放了一个临时的,然后马上读回来。对于大向量,这超出了缓存。这比表达式模板更糟糕。他们可以在 1 个循环中完成整个事情。ET 可以执行上述代码,相当于:

我想知道 lambda 与移动语义或任何其他新功能是否可以与 ET 一样好。有什么想法吗?

编辑:

基本上,使用 ET 技术,编译器构建一个类似于代数表达式及其类型系统的解析树。这棵树由内部节点和叶节点组成。内部节点表示操作(加法、乘法等),叶节点表示对数据对象的引用。

我试图以堆栈机器的方式思考整个计算过程:从操作堆栈中获取一个操作,然后从参数堆栈中提取下一个参数并评估该操作。将结果放回堆栈等待操作。

为了表示这两个不同的对象(操作堆栈和数据叶堆栈),我将std::tuple用于操作的 a 和 std::tuple用于数据叶的 a 捆绑到一个std::pair<>. 最初我使用了 a std:vector,但这导致了运行时开销。

整个过程分为两个阶段: 堆栈机器初始化,其中操作和参数堆栈被初始化。以及通过将配对容器分配给向量来触发的评估阶段。

我创建了一个类Vec,它包含一个私有array<int,5>(有效负载)并且具有一个采用“表达式”的重载赋值运算符。

全局operator*对于 take 和 "expression" 的所有组合都被重载, Vec以便在我们拥有的不仅仅是a*b. (注意,我将这个教育示例切换到乘法 - 基本上是为了imull在汇编程序中快速发现。)

在评估开始之前首先要做的是从所涉及的Vec对象中“提取”值并初始化参数堆栈。这对于周围没有不同类型的对象是必要的:可索引的向量和不可索引的结果。这就是 Extractor它的用途。又是一件好事:使用了可变参数模板,在这种情况下不会产生运行时开销(所有这些都是在编译时完成的)。

整个事情都有效。表达式得到了很好的评估(我还添加了附加项,但为了适合代码,这里省略了)。您可以在下面看到汇编器输出。只是原始计算,完全符合您的要求:与 ET 技术相当。

结果。C++11 的新语言特性提供了可变参数模板(连同模板元编程),开辟了编译时计算的领域。我在这里展示了如何使用可变参数模板的好处来生成与传统 ET 技术一样好的代码。

生成的汇编器g++-4.6 -O3(我不得不在向量初始化中加入一些运行时依赖,这样编译器就不会在编译时计算整个事情,你实际上会看到imullinstaructions。)

0 投票
2 回答
520 浏览

c++ - 为什么 std::basic_string 不支持通过表达式模板连接?

Qt 的QStrings 可以连接起来,通过operator%它使用表达式模板来预先计算结果字符串的大小并优化对operator+. 有关更多信息,请参阅我的这个问题。

为什么没有std::basic_string采用类似的结构?这甚至允许每个 C++11 吗?我只看到了优点,并且很明显,库实现者可以在他们想要的时候破坏 ABI 兼容性(C++11 甚至为 libstdc++ 提供了一个很好的理由)。

0 投票
1 回答
921 浏览

c++ - 带有表达式模板问题的 c++ 矩阵

我必须制作一个使用矩阵的学校项目。在 Visual Studio 2010 中,一切正常。测试服务器具有“matrix_base”和主要功能,例如:

服务器中的编译器是带有 -static -O2 参数的 g++。我得到如下错误:

/var/www/F/I704e/3/1/teszt1.cpp:在函数'int main()'中:

/var/www/F/I704e/3/1/teszt1.cpp:42: 错误: 'operator+(const my_matrix&, const my_matrixAdd&) 中的 'operator+' 不匹配 [with T = int, int N = 5, int M = 3, LeftOp = my_matrix, RightOp = my_matrix](((const my_matrixAdd, my_matrix >&)((const my_matrixAdd, my_matrix >*)(& operator+(const my_matrix&, const my_matrix&) [with T = int, int N = 5 , int M = 3](((const my_matrix&)((const my_matrix*)(& mtx3)))))))) + operator+(const my_matrixAdd&, const my_matrix&) [with T = int, int N = 5, int M = 3, LeftOp = my_matrix, RightOp = my_matrix](((const my_matrix&)((const my_matrix*)(& mtx6))))'</p>

就像:

在 /var/www/F/I704e/3/1/teszt1.cpp:6 包含的文件中:

/var/www/Hallg/I704e/3/h145172/7/feladat.cpp:在函数 'my_matrixAdd, my_matrixAdd > operator+(const my_matrixAdd&, const my_matrixAdd&) [with T = int, int N = 5, int M = 3, LeftOp = my_matrix,RightOp = my_matrix]':

请帮我!谢谢你!

0 投票
2 回答
185 浏览

c++ - c++ 函数重载、表达式模板和命名空间

我正在开发一个基于表达式模板和运算符/函数重载的自动微分工具。例如,模板std::max函数已成功重载:

但在如下代码中

如果命名空间被省略,则使用std:: ,而对于某些其他函数,则使用ead::。是否有强制编译器始终选择 ead:: 命名空间的技巧,例如用于 max 函数?(请不要使用 C++11 功能)为什么编译器认为 std::max 更匹配?
好的,我知道在函数名称之前写ead::没什么大不了的,但我想避免用户打字。

0 投票
2 回答
306 浏览

c++ - 在 Visual C++ 中开发静态库以进行高效的数值计算

我有以下问题:我需要在 Visual C++ 中开发一个静态库 (*.lib) 以进行高效的数值计算。我已经开始定义一个新的模板类“矩阵”,并且我已经读到使用表达式模板可以实现最佳效率。但我也读过(并且经历过)我不能将表达式模板包含在静态库中,因为您需要显式地实例化所有组合。

所以 - 例如 - 如果我想在一个新项目中做:

导入我的 *.lib 文件,我必须在我的静态库中创建 3 种不同的组合以允许等式 M_C = Expression。

有没有一种方法或“最佳实践”来简化静态库中的显式实例化?或者,有没有表达模板的替代方案,可以在没有导出问题的情况下实现相同的效率?为了澄清起见,我需要保留紧凑符号的可能性,例如: M_C = M_A + M_B + 2 * M_D;

谢谢你。

附言。我添加了更多细节以更好地解释:

如果我创建我的静态库,我可以在外部项目中使用它,但我必须导出所有模板专业化。模板类 __declspec(dllexport) 矩阵;模板类 __declspec(dllexport) 矩阵;

等等...

问题是我必须对所有可能的表达式做同样的事情以允许等式(例如,M_A = M_B + M_C)。我必须导出类似这样的内容:模板类 LibraryNameSpace::Matrix const & __thiscall LibraryNameSpace::Matrix::operator=,int>(class LibraryNameSpace::myExpression,int>);

如果不将所有代码包含在 lib 文件中,对我来说没有问题:我可以毫无问题地使用我的库。该问题与在静态库中包含表达式模板有关。我需要这样做来屏蔽代码并且不让最终用户能够阅读它。

0 投票
1 回答
133 浏览

c++ - Boost Phoenix 中嵌套 let 块中的变量隐藏

当“内部”局部变量隐藏“外部”局部变量时,我在 Boost Phoenix 中的嵌套 let 块遇到了一些问题。即使使用此处文档中的“可见性”示例,此处显示:

我收到以下错误:

有谁知道我如何在 Phoenix 的内部 let 块的范围内“隐藏”这样一个变量?我目前正在使用带有 GCC 版本 4.8 快照的 Ubuntu 13.04;铿锵声 3.2; 提升 1.49;还有 Boost 1.53。

0 投票
0 回答
130 浏览

c++ - 表达式模板,变量和值的添加

我有一个表达式模板,它在给定表达式中添加一个带有常量的变量。我想将其转换为添加具有任何给定数字的变量。常量和变量的结构:

这是表达式结构:

这是加法结构:

这是运算符模板:

这是头文件:

这实际上不是我的代码,但我已将所有基本算术运算添加到代码中。

有什么想法吗?我是C++模板的新手,我并没有真正了解它。

0 投票
1 回答
257 浏览

c++ - 实现 A(:,k)=b; C++ 矩阵库中的类 Matlab 语法

我自己开发了一个基于表达式模板的 C++ 矩阵类。我重载了()运算符,以便我可以读取或写入元素矩阵,例如,

分别。我还实现了一个Range类来启用类似 Matlab 的读取

模板Matrix类示例为

我现在想启用类似 Matlab 的作业

其中B是一个合适的矩阵。

我认为,要实现上面类似 Matlab 的语法,有两种可能性是

  1. 重载()运算符,使其返回一个指针数组,然后重载=运算符,以便后者可以在指针数组和 a 之间进行Matrix操作
  2. 利用上面指出的已经执行的()运算符重载并重载运=算符,以便后者可以在表达式和Matrix.

也许第一个选项不是很方便,特别是对于非常大的矩阵。我对么?是否有其他更有效/更有效的可能性使用可能更复杂的 C++ 功能(例如,移动语义)?

非常感谢您的帮助。