定义宏以改进特定函数的语法
Defining macro improving syntax of specific function
我创建了一个声明为:的函数
template <typename Container, typename Task>
void parallel_for_each(Container &container, Task task,
unsigned number_of_threads = std::thread::hardware_concurrency())
不难猜测它应该做什么。我想创建一个宏,简化这个函数的语法,并使其语法"像循环一样"。我想出了一个主意:
#define in ,
#define pforeach(Z,X,Y) parallel_for_each(X,[](Z)->void{Y;})
用途:
pforeach(double &element, vec,
{
element *= 2;
});
工作如预期,但这一个:
pforeach(double &element in vec,
{
element *= 2;
element /= 2;
});
给出错误
宏"pforeach"需要3个参数,但给定时只有2个
你知道如何编写一个允许"更好"语法的宏吗?为什么"in"在我的代码中不代表逗号?
in
没有被替换的原因是它出现在类似函数的宏的参数中,但要替换它,必须先将这些参数传播到另一个宏:尝试
#define in ,
#define pforeach_(Z,X,Y) parallel_for_each(X,[](Z)->void{Y;})
#define pforeach(Z,X,Y) pforeach_(Z,X,Y)
注意:将in
定义为,
不会有好结果!
添加"更好"语法的想法:
template <typename Container>
struct Helper {
Container&& c;
template <typename Arg>
void operator=(Arg&& arg) {
parallel_for_each(std::forward<Container>(c), std::forward<Arg>(arg));
}
};
#define CONCAT_(a,b) a##b
#define CONCAT(a,b) CONCAT_(a,b)
// Easier with Boost.PP
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC(i) CONCAT(DEC_,i)
#define pforeach(Z, ...)
Helper<decltype((__VA_ARGS__))> CONCAT(_unused_obj, __COUNTER__){__VA_ARGS__};
CONCAT(_unused_obj, DEC(__COUNTER__))=[](Z)
可用作
int a[] = {1, 2, 3};
pforeach(int i, a) {
std::cout << i << ", ";
};
pforeach(int i, std::vector<int>{1, 2, 3}) {
std::cout << -i << ", ";
};
演示
不过有几个缺点。到目前为止,我会坚持你所拥有的。
为什么"in"在我的代码中不代表逗号?
因为该替换是在确定宏参数后执行的。引用标准草案N3797,§16.3.1论点替代:
在确定了调用类似函数的宏的参数后,将进行参数替换。。。在被替换之前,每个参数的预处理标记都被完全宏替换,就好像它们构成了预处理文件的其余部分一样;没有其他预处理令牌可用。
因此,预处理器将pforeach(double &element in vec, {})
识别为一个类似函数的宏调用,具有两个参数:
- 第一个由标记
double
、&
、in
和vec
组成,并绑定到参数Z
- 第二个由标记
{
和}
组成,并绑定到参数X
您显然错过了参数Y
你知道如何编写一个允许"更好"语法的宏吗?
很难回答,这是品味问题。无论如何,C++有丰富的能力用运算符重载修补语法,但你不能用它来构建DSL,所以最好使用默认语法,它没有那么难看(也让它很容易阅读):
parallel_for_each(vec, [](double& el){ el *= 2; })
没有宏语言。宏由C/C++预处理器处理。预处理器的实现方式可能有所不同。
大多数预处理器都期望您传递确切数量的参数。我发现GNU预处理器对参数的检查不那么严格,这允许一种可变列表。但总的来说,宏对你的任务没有帮助。
我建议在函数中而不是在宏中编写简短的语句。内联函数与宏一样快速、简短,但类型安全。此外,该功能允许默认参数值。所以你可以跳过一些东西。
试图改进@Columbo:的想法
template <typename Container>
struct __pforeach__helper {
Container &&c;
template <typename Arg>
void operator=(Arg&& arg) {
parallel_for_each(std::forward<Container>(c), std::forward<Arg>(arg));
}
};
//additional helper function
template <typename Container>
__pforeach__helper<Container> __create__pforeach__helper(Container &&c)
{
return __pforeach__helper<Container>(__pforeach__helper<Container>{c});
}
#define pforeach(Z,C)
__create__pforeach__helper(C)=[](Z)
它不依赖于__COUNTER__
,也不需要定义DEC_x
宏。欢迎任何反馈!
- C++使用 rand 定义函数语法
- QObject::连接不起作用 - 使用函数语法找不到信号
- C++ std::函数语法问题
- 如何在不更改现有函数语法的情况下将普通指针替换为共享指针
- 模板化函数语法错误中使用的模板化类中的嵌套类
- C 变化函数语法
- 返回语句中的构造函数语法
- 复制构造函数语法错误:myclass 没有成员 mymember
- C++.传递给函数.语法问题
- C++可视化工作室函数语法突出显示
- 在 c++ 中移动 2d 数组的构造函数(语法逻辑不清楚):
- c 通过值或指针函数语法
- 正确的朋友模板函数语法
- C++类构造函数语法的解释
- C++ 使用指针移动构造函数(*&&&语法)
- 复制构造函数语法并显示构造函数的值
- 回调函数语法
- 类模板专用化中的成员函数语法
- C++学习函数语法
- 使用模板 C++ 的友元函数语法错误