条件宏文本替换
Conditional macro text replacement
我的直觉是这是不可能的,但我不是专家。以下是我想做的:
#define KEY(i) #if (i == 0) KeyClassA(arg.fieldA)
#elif (i == 1) KeyClassB(arg.fieldB)
//...
#endif
//inside a function with given arg
for(int i = 0; i < N; i++) {
Data* data = array[i]->find(KEY(i));
//do things with data
}
该代码显然比C++代码更伪代码,我个人认为这样的东西不会编译,但我的意图应该很明确:根据数组中适当的数据结构为 find 函数提供一个临时类对象。也就是说,数组中的每个数据结构都需要不同的键匹配类。
宏文本替换似乎是尝试实现这一目标的"最聪明"的方法,但我显然欢迎任何其他想法来让这样的东西发挥作用。
文本替换不能解决您的问题,因为索引i
仅在运行时已知。宏甚至在编译开始之前就被处理。
如果在编译时不知道N
,则需要使用条件结构的某种组合,并且可能需要使用循环。如果 KeyClass*
es 的数量是固定的(似乎是这种情况(,您可以执行以下操作:
void Foo(int N, Array& array, const Bar& arg)
{
if(N > 3 || N <= 0) return;
Data* data = array[0]->find(KeyClassA(arg.fieldA));
// DoSomething(data);
if(N == 1) return;
data = array[1]->find(KeyClassB(arg.fieldB));
// DoSomething(data);
if(N == 2) return;
data = array[2]->find(KeyClassC(arg.fieldC));
// DoSomething(data);
}
将所有公共代码放在 DoSomething()
函数中(最好使用更好的函数名称(,这样您就不会重复自己所有可能的有效值N
。
但是,如果在编译时知道N
,则可以简单地展开循环。
void Foo(Array& array, const Bar& arg)
{
Data* data = array[0]->find(KeyClassA(arg.fieldA));
// DoSomething(data);
data = array[1]->find(KeyClassB(arg.fieldB));
// DoSomething(data);
data = array[2]->find(KeyClassC(arg.fieldC));
// DoSomething(data);
}
如果您不想自己展开循环,您甚至可以花哨地使用模板元编程,尽管这对于您正在做的事情来说可能是矫枉过正的:
// The basic idea using template specializations
template<int i>
struct GetKey;
template<>
struct GetKey<0>
{
KeyClassA From(const Bar& arg) { return KeyClassA(arg.fieldA); }
};
template<>
struct GetKey<1>
{
KeyClassB From(const Bar& arg) { return KeyClassB(arg.fieldB); }
};
template<>
struct GetKey<2>
{
KeyClassC From(const Bar& arg) { return KeyClassC(arg.fieldC); }
};
template<int i, int N>
struct Iterate
{
static void Body(Array& array, const Bar& arg)
{
Data* data = array[i]->find(GetKey<i>().From(arg));
// DoSomething(data);
Iterate<i+1, N>::Body(array, arg);
}
};
template<int N>
struct Iterate<N, N>
{
static void Body(Array& array, const Bar&) {}
};
void Foo(Array& array, const Bar& arg)
{
Iterate<0, 3>::Body(array, arg);
}
无论如何都是不可能的,因为i
不是编译时常量。(不仅仅是编译时常量,而是预处理器阶段的常量(
因此,您必须使用正常的 if 语句C++来执行此操作。(或开关(
根据我认为您要做的事情,使用循环会使它比需要的更复杂。只需全部写出来,就不需要任何循环或 if 语句。
array[0]->find(arg.fieldA);
array[1]->find(arg.fieldB);
...
(你似乎也没有对Data* data
做任何事情(
编辑:有新信息。
在这种情况下,您可以将循环体放入函数调用中。像这样:
void loop_body(KeyClass &key, /* other parameters */ ){
Data* data = array[0]->find(key);
// Rest of the body
}
只需为每个字段调用它。
loop_body(arg.fieldA);
loop_body(arg.fieldB);
...
你试过#define KEY(i) i?KeyClassB(arg.fieldB):KeyClassA(arg.fieldA)
吗
#define KEY(i) ((i) == 0 ? KeyClassA(arg.fieldA) :
(i) == 1 ? KeyClassB(arg.fieldB) :
...)
事实上,这是一个宏真的不会给你带来任何东西;计算仍然必须在运行时完成,因为它取决于i
的值。
作为内联函数,这将更有意义。
- 使用 constexpr 替换 #define 和 #ifdef 进行条件编译
- 尝试将文本文件中的整数替换为用户输入的整数 [C++]
- 如何使用regex_replace将子字符串替换为字符串中的另一个子字符串,同时保持整个文本完整?
- 如何在给定文本中用字符数组替换符号
- C++代码在 for 循环的条件下给出运行时错误,而如果它被具有相同意义的代码替换,则编译正确
- 创建程序以从给定的.txt文件中查找文本,替换并计算单词
- 将文本流中一个字符串的所有匹配项替换为另一个字符串
- Haskell中用多态性替换条件的等效模式是什么?
- 将循环(以及其中的条件)替换为按索引直接访问
- 外壳追加重定向替换现有文本
- Visual C 以前的文本在终端中删除并替换为新文本
- 尝试在自定义 QT 创建器文本编辑器中创建查找和替换循环.我似乎无法设置光标位置
- 计算文本文件中行数的最佳条件是什么
- 我将如何替换命令提示符上的文本?C
- 如何替换QT QML中的变体数组文本
- 从文本文件中读取并替换文本,C
- 如何用不同的文本替换文本文件上的某一行
- C++如何创建"绑定"字符串文本替换方法?
- 用C++宏将文本替换为空
- 在 C++11 中使用用户定义的文本的条件包含