宏来重复几乎相同的代码
Macro to repeat almost the same code
我必须根据编译时常数参数编写相同的代码,例如:
map["text 0"] = vec[0];
map["text 1"] = vec[1];
...
map["text n"] = vec[n];
问题是,当我写代码时,我不知道n
,我接收它作为模板参数。显而易见的解决方案是使用一个循环并在循环内生成"text k"
并使用vec[k]
,但是这有运行时开销,当它应该在编译时完成时。另一个解决方案是针对不同的N
值对函数进行专门化,但是这样的话,我将不得不多次手工编写相同的代码,并且没有理由使其成为模板。
我知道有一些智能宏可以重复类似的事情N次(如BOOST_PP_REPEAT
宏家族),但我找不到一个解决方案,我的具体问题。
除非您有非常非常严格的性能约束,否则没有理由担心运行时开销。无论如何,插入都将在运行时执行,并且插入时间肯定会支配更改字符串中字符所需的时间。
此外,宏很难调试和维护:尽可能避免使用它们。在这里,我建议展开一个简单的循环:
std::string s = "text 0";
std::map<std::string, int> m;
for (int i = 0; i < N; i++)
{
m[s] = vec[i];
s[5] = '1' + i; // This is going to be the run-time overhead...
}
如果您的数字增长大于9
,在c++ 11中您可以使用to_string()
函数将整数转换为字符串:
std::string const s = "text ";
std::map<std::string, int> m;
for (int i = 0; i < N; i++)
{
m[s + std::to_string(i)] = vec[i];
}
如果性能将被证明是一个问题,那么您可以尝试基于宏的更核心的方法。但是,如果您的测量结果不会显示出很大的开销,那么更倾向于简单性和清晰性并展开一个简单的循环。
我相信下面这些应该可以起作用:
#include <boost/preprocessor.hpp>
//... or just the required sub-headers
// Will generate code for 0, 1, ... (N_END - 1)
#define N_END 10
#define ONE_ASSIGNMENT(maZ, maIter, maData)
if (maIter <= n) map["text " BOOST_PP_STRINGIZE(maIter)] = vec[maIter];
BOOST_PP_REPEAT(N_END, ONE_ASSIGNMENT, %%) //this generates the code
#undef ONE_ASSIGNMENT
#undef N_END
注意,if()
比较的是一个字面值和一个模板参数(n
),所以任何称职的优化器都会从中生成无分支的代码。
我使用%%
作为"此值从未使用过"。它被传递到maData
参数中,所以如果你有一些有用的东西要实际传递(比如"text "
),你可以这样做。
对我来说,重复似乎不是问题,但编译时将int转换为string以及随后的连接却是问题。重复问题可以通过以下技术(未经测试)来解决:
template<k,l> struct fill_vector {
static void doIt (... & vec) {
vec [INT_TO_TEXT (k)] = k;
fill_vector<k+1,l-1>::doIt (vec);
}
};
template<k> struct fill_vector<k,0> {
static void doIt (... & vec) {
vec [INT_TO_TEXT (k)] = k;
}
};
//...
fill_vector<0,n>::doIt (vec);
也许有人知道如何实现INT_TO_TEXT
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值