我已经看到一些问题要求变量FOR_EACH宏的变化.但遗憾的是,提供的答案与VC++ 10不兼容,因为它在传递给另一个宏时将__VA_ARGS __扩展为一个参数.请有人可以提供符合C++ 11(因此向前兼容)的版本,仍然适用于VC++ 10.也许使用经常提到的"解决方法" #define EXPAND(x) x,但是我不知道在哪里放这个以便获得,例如,后一个通用部分的答案在VC++ 10中工作.
为了澄清,预期的行为是FOR_EACH(x, a, b, ...)生成x(a) x(b), ...,其中x是另一个宏.
作为问题的一个例子,有没有办法partialconcat在下面的代码中实现宏?
#define apply(f, x) f(x)
apply(partialconcat(he),llo) //should produce hello
Run Code Online (Sandbox Code Playgroud)
编辑:
这是另一个例子,给定一个FOR_EACH可变参数宏(参见另一个问题的答案中的示例实现).
假设我想在几个对象上调用一个成员,可能在另一个宏中用于更大的目的.我想要一个宏callAmber,其行为如下:
FOR_EACH(callMember(someMemberFunction), a, b, c);
Run Code Online (Sandbox Code Playgroud)
产生
a.someMemberFunction(); b.someMemberFunction(); c.someMemberFunction();
Run Code Online (Sandbox Code Playgroud)
这需要callMember(someMember)产生一个行为像的宏
#define callMember_someMember(o) o.someMember()
Run Code Online (Sandbox Code Playgroud) 假设我有一个创建QIODevice(例如QFile)的函数,然后返回一个指向QIODevice构造的QDataStream的指针.在这里处理内存分配的最佳方法是什么?显然,QIODevice必须被堆分配以在函数终止时保持对QDataStream可用,但是QDataStream的破坏不会破坏或关闭设备.有没有一种标准的方法来处理这个看似常见的问题?理想情况下,我想要一个函数,它返回一个对象(不是指向对象的指针),其行为类似于QDataStream,但在销毁时会关闭设备.有效地是标准库输入流.
示例代码:
QDataStream* getStream(const QString& filename) {
QFile* file = new QFile(filename); // needs to be explicitly deleted later
file->open(QIODevice::ReadOnly);
QDataStream* out = new QDataStream(&file); // same here
return out;
}
Run Code Online (Sandbox Code Playgroud) 如果我有一个条件循环应该表现得好像它开始部分通过,那么什么才算是编码的最好方法?包含goto类似以下代码段的代码是否可以接受?
goto first_itr;
do {
doSomeStuff();
first_itr:
doSomeOtherStuff();
} while(condition);
Run Code Online (Sandbox Code Playgroud)
我能看到的明显效率较低的替代方案是引入一个标志和一个条件doSomeStuff();,产生以下内容:
bool first = true;
do {
if(first)
first = false;
else
doSomeStuff();
doSomeOtherStuff();
} while(condition);
Run Code Online (Sandbox Code Playgroud)
这是我在这种情况下通常使用的方法.可以依靠编译器通过有效地将其转换为第一个片段来改善它吗?
我可以想到的其他替代方案,避免goto和条件会涉及重复代码,但这似乎比一个更糟糕的代码味道goto.
此外,如果循环对性能至关重要,那么答案会有所不同,额外条件的开销会显着降低性能吗?