有没有办法在一个定义两种不同类型的变量循环初始化函数?
-
21-08-2019 - |
题
可以定义相同类型的2个变量的for循环:
int main() {
for (int i = 0, j = 0; i < 10; i += 1, j = 2*i) {
cout << j << endl;
}
}
但它是非法的定义不同类型的变量:
int main() {
for (int i = 0, float j = 0.0; i < 10; i += 1, j = 2*i) {
cout << j << endl;
}
}
有没有办法做到这一点? (我不需要使用环,只是i
内部j
。)
如果你已经完全破解和晦涩的解决方案,这对我来说OK。
在我知道你可以只使用double
两个变量这个人为的例子。我在寻找一个普遍的答案。
请不建议移动任何变量之外的身体,也许不能用于我作为一个是具有消失只是循环后for语句是被封闭在我foreach
宏观的迭代器:
#define foreach(var, iter, instr) { \
typeof(iter) var##IT = iter; \
typeof(iter)::Element var = *var##IT; \
for (; var##_iterIT.is_still_ok(); ++var##IT, var = *var#IT) { \
instr; \
} \
}
它可以如此使用:
foreach(ii, collection, {
cout << ii;
}).
但我需要的东西,将这样的使用:
foreach(ii, collection)
cout << ii;
请不要引入任何运行时开销(但它可能是缓慢的编译)。
解决方案
下面是使用升压预处理器的版本(这是玩票对于真实世界的回答,请@厨房的上面一个):
FOR((int i = 0)(int j = 0.0), i < 10, (i += 1, j = 2 * i)) {
}
第一部分指定声明的序列:(a)(b)...
。后声明的变量可以参考之前声明的变量。第二和第三部分是如常。其中逗号发生在第二和第三部分,括号可以用来防止它们分离宏参数。
有已知我两个技巧用于声明是在宏外面加入的复合语句后可见的变量。第一种使用情况下,像一个,如果:
if(int k = 0) ; else COMPOUND_STATEMENT
然后k
是可见的。当然,它总是以评估false
。因此,它不能被我们利用。其他上下文是这一个:
for(int k = 0; ...; ...) COMPOUND_STATEMENT
这就是我要在这里使用。我们还得小心,只让COMPOUND_STATEMENT
的一次迭代。实际for
循环,它的增量和条件检查具有来在端部,因此在所附复合语句appertains到它。
#include <boost/preprocessor.hpp>
#include <iostream>
#define EMIT_DEC_(R,D,DEC) \
for(DEC; !_k; )
#define FOR(DECS, COND, INC) \
if(bool _k = false) ; else \
BOOST_PP_SEQ_FOR_EACH(EMIT_DEC_, DECS, DECS) \
for(_k = true; COND; INC)
int main() {
FOR((int i = 0)(float j = 0.0f), i < 10, (i += 1, j = 2 * i)) {
std::cout << j << std::endl;
}
}
它创建了一堆for
语句,每个嵌套到另一个。它扩展为:
if(bool _k = false) ; else
for(int i = 0; !_k; )
for(float j = 0.0f; !_k; )
for(_k = true; i < 10; (i += 1, j = 2 * i)) {
std::cout << j << std::endl;
}
其他提示
请不建议将任何的 变量之外的身体, 可能无法使用我的 迭代器有消失刚过 循环。
您可以这样做:
#include <iostream>
int main( int, char *[] ) {
{
float j = 0.0;
for ( int i = 0; i < 10; i += 1, j = 2*i ) {
std::cout << j << std::endl;
}
}
float j = 2.0; // works
std::cout << j << std::endl;
return 0;
}
嗯,这是丑陋的。但是,你可以使用对。
int main() {
for (std::pair<int,float> p(0,0.0f);
p.first < 10;
p.first += 1, p.second = 2*p.first) {
cout << p.second << endl;
}
}
{
int i = 0;
float j = 0.0;
for ( ; i < 10; i += 1, j = 2*i) {
cout << j << endl;
}
}
的变量 “消失” 的块之后。
这将使得在迭代器(或在此情况下,浮点)消失时没有更多的需要它:
int main() {
// some code...
{
float j = 0.0;
for (int i = 0; i < 10; i += 1, j = 2*i) {
cout << j << endl;
}
}
// more code...
}
如果您遇到麻烦宏,有一个标准do..while
技巧,完美的作品:
#define MYFOR(init, test, post, body) \
do \
{ \
init \
for( ; test; post) \
body \
} while(0)
如下使用它:
MYFOR( int i = 0; float j = 0.0f; , i < 10 , (i += 1, j = 2.0f * i),
{
cout << j << endl;
} );
这是丑陋的,但你想要做什么:i
和j
的范围从宏观的do..while
循环的限制,它要求在最后一个分号,所以你不会把它在得到咬伤的if / else语句的谓词。
这是一个也难看,而且对于在与声明一些给定的名称和类型的多个变量提供了一些一般的方式for循环
int main() {
for (struct { int i; float j; } x = { };
x.i < 10; x.i += 1, x.j = 2 * x.i) {
cout << x.j << endl;
}
}
修改强>:问题已经改变一次。现在的问题明确希望实现一个foreach循环。最简单的答案:
#include <boost/foreach.hpp>
void( std::vector<int>& v ) {
BOOST_FOREACH( int & x, v ) {
x = x*2;
}
}
<强>注射的可变成代码块强>
这不打算作为一个答案,但表现出一个更一般的技术用于注射可变成代码块。看来,如果宏中的OP试图定义可以使用,即使它在一些开销招致的
有一对夫妇,在那里你可以定义不同的作用域变量的地方。可以定义任意码块中的变量,并且其寿命将是该特定块的结尾。您可以在for循环的括号定义一个变量,并且范围将是环形块。还可以定义一个变量的块,如果内,其范围将是的如果(包括else子句)。
可以结合以上这些选项在外部创建和注入变量成代码块,而无需创建一个变量,其寿命超过该块的。 。一个实际的例子将被限定foreach循环(简化为仅在STL容器工作调用的语法是:
void f( std::vector<int>& container )
{
INTVECTOR_FOREACH( int & x, container )
{
x = x*2;
}
}
使用类似的其它语言的foreach语义:x被引用在容器中的每个元素,从而使函数实际上加倍整数向量内的每个值
现在简化宏的代码:
#define INTVECTOR_FOREACH( variable, container ) \
for ( std::vector<int>::iterator it = container.begin(); it!=container.end(); ++it ) \
if ( bool condition=false ) {} else \
for ( variable = *it; !condition; condition=true )
归纳为任何容器类型的宏需要一些元编程落在出了问题的背景下,但它是如何工作的想法(我希望)应该不会太难追随。
在外部的的的迭代的容器,在每次迭代中,我们执行另一个的的仅一次限定所述迭代变量(INT&X在示例代码)。我们需要一个条件来控制内部循环的迭代(1)的数量,并且该条件被注入一个如果。我们选择,如果失败,这样我们就可以确保用户不会得到意想不到的结果,如果她在循环后写一个else ...宏是棘手的做成了。
请不建议移动任何变量之外的身体,可能无法使用,我作为迭代器具有在循环后就此消失。
您仍然可以做到这一点,并把在大括号整件事作出额外的变量超出范围。
int main()
{
{
float j = 0.0;
for (int i = 0; i < 10; i += 1, j = 2*i)
{
cout << j << endl;
}
}
// more code...
}
此方式j
将在循环后右出去的范围。
通过要求你给我能想到的最简单的代码是:
for ( int i = 0; i < 10; ++i )
{
float f = i * 2;
std::cout << f << std::endl;
}
您只使用˚F作为的两倍值i 。寿命被限制在环路和(至少在简化问题,你提供)浮子是廉价创建(确切地便宜,因为分配)。
如果实际的浮(我假设由于i是不是真正的int中,f可以不是浮动要么)比重新分配值昂贵得多,那么其他的解决方案的结构一个额外的一对大括号内包封以限制范围将是最好的选择。
int main() {
for (int i = 0, float j = 0.0; i < 10; i += 1, j = 2*i) {
cout << j << endl;
}
}
也许我是密集的,但为什么你甚至要申报浮动?你只是“把它扔掉”当你离开的循环反正。正确?
for(int i=0; i<10; ++i)
cout << (float)2*i << endl;
为什么你需要J1
您说的i
是你自己的类型,你只需要生成j
出i
的,对不对?简单。添加一个成员函数i
的类来生成j
值,并使用该始终。你可能甚至还令宏“隐藏”的号召,该成员函数,如果你想要的。 : - )
你为什么不只是声明和初始化之外的变量循环?您还可以测试并增加你有现在。