c++ - 如何在 C++ 预处理器宏中处理数组元素?
问题描述
对于家庭作业,我们被要求编写一个预处理器宏来对数组的元素求和。
我的问题是,如何以可以扩展为总和(或元素上的任何其他数学运算)的方式处理宏中的数组元素?
我们的书中没有提到处理数组元素甚至访问它们,而且我在网上找不到很多有用的资源,因为宏不是处理此类事情的典型方法。我知道有更好的方法来做这样的事情,但我知道这个想法是为了让我们更好地熟悉预处理器宏。
当我以函数的形式编写宏时,我不知道如何将总和“返回”给程序。我能想到的让宏扩展为总和的唯一方法是递归完成,我什至不确定你是否可以使用宏进行递归。我编写了一个成功扩展为数组大小的宏,但我不确定从那里往哪个方向发展。
解决方案
这是使用 c++14 的答案:
#include <array>
#include <iostream>
#include <numeric>
#include <type_traits>
#include <vector>
#define SUM(ARY) \
std::accumulate( \
std::begin(ARY), \
std::end(ARY), \
std::remove_reference_t<decltype(ARY[0])>{})
int
main()
{
auto ary1 = std::array< int, 5 >{1,2,3,4,5};
std::cout << SUM(ary1) << "\n";
int ary2[] = {1,2,3,4,5};
std::cout << SUM(ary2) << "\n";
auto ary3 = std::vector< int >{1, 2, 3, 4, 5};
std::cout << SUM(ary3) << "\n";
double ary4[] = {1.1,2.2,3.3,4.4,5.5};
std::cout << SUM(ary4) << "\n";
}
请注意,您不会从宏中“返回”。宏是文本替换。在上面出现的地方,它被宏定义SUM(ary)
的扩展文本替换。SUM(ARY)
您可以将此扩展到其他操作:
#include <array>
#include <iostream>
#include <numeric>
#define OP_ON_ARY(ARY, OP) \
std::accumulate( \
std::next(std::begin(ARY)), \
std::end(ARY), \
*std::begin(ARY), \
[](auto a, auto b) { return a OP b; } \
)
int
main()
{
auto ary = std::array< int, 5 >{1,2,3,4,5};
std::cout << OP_ON_ARY(ary, +) << "\n";
std::cout << OP_ON_ARY(ary, -) << "\n";
std::cout << OP_ON_ARY(ary, *) << "\n";
}
但是使用函数而不是宏更符合现代 c++ 的精神。
#include <array>
#include <iostream>
#include <numeric>
#include <vector>
template< typename Ary >
auto sum(Ary const & ary)
{
return std::accumulate(
std::begin(ary),
std::end(ary),
decltype(ary[0]){});
}
int
main()
{
auto ary1 = std::array< int, 5 >{1,2,3,4,5};
std::cout << sum(ary1) << "\n";
int ary2[] = {1,2,3,4,5};
std::cout << sum(ary2) << "\n";
auto ary3 = std::vector< int >{1, 2, 3, 4, 5};
std::cout << sum(ary3) << "\n";
double ary4[] = {1.1,2.2,3.3,4.4,5.5};
std::cout << sum(ary4) << "\n";
}
推荐阅读
- ruby-on-rails - 如何为 add_column 进行可逆迁移
- laravel - LogicException 无法为序列化准备路由 [api/user]。使用闭包
- javascript - 之前没有等待功能完成的功能?
- arrays - Powershell - 从数组中选择名称并将电子邮件发送到 DL
- pandas - 如何基于行子集进行滚动计算
- javascript - 刷新页面后,如何确保从 localStorage 显示正确的数据?
- mysql - 连接失败 mySQL for Excel 1.3.8
- python-2.7 - Revit API Python SetBoxCenter() 应用于多个视口
- wordpress - 神秘的 WordPress 问题——想不通
- javascript - 如何通过使用前面的数字来减小字符串的大小?