답변:
C ++ 17 : 예! 구조적 바인딩 선언을 사용해야합니다 . 이 구문은 gcc 및 clang에서 수년 동안 지원되었습니다 (gcc-7 및 clang-4.0 이후) ( clang live 예제 ). 이를 통해 다음과 같이 튜플의 포장을 풀 수 있습니다.
for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) {
// ...
}
위의 내용은 다음과 같습니다.
int i
로 설정 1
double f
로 설정 1.0
std::string s
로 설정 "ab"
#include <tuple>
이런 종류의 선언 을 확인하십시오 .
유형 이름을 지정하려면을 사용하여 tuple
입력 한대로 모두 유형 을 입력 하여 정확한 유형을 지정할 수 있습니다 std::string
. 예를 들면 다음과 같습니다.
auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}
이에 대한 구체적인 적용은지도를 반복하고 키와 가치를 얻는 것입니다.
std::unordered_map<K, V> m = { /*...*/ };
for (auto& [key, value] : m) {
// ...
}
C ++ 14 : type-based를 추가하여 C ++ 11 (아래)과 동일하게 수행 할 수 있습니다 std::get
. 따라서 std::get<0>(t)
아래 예 대신 을 사용할 수 있습니다 std::get<int>(t)
.
C ++ 11 : 둘 이상의 객체 std::make_pair
뿐만 아니라이를 수행 할 수 있습니다 std::make_tuple
.
for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
std::cout << p.second << std::endl;
}
std::make_pair
에서 두 개의 인수를 반환합니다 std::pair
. 요소는 액세스 할 수 있습니다 .first
와 .second
.
두 개 이상의 객체의 경우 std::tuple
for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
std::get<0>(t) < 10;
++std::get<0>(t)) {
std::cout << std::get<1>(t) << std::endl; // cout Hello world
std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
}
std::make_tuple
varidic 템플릿은 여러 가지 인수로 구성된 튜플을 구성합니다 (물론 기술적 제한이 있음). 요소는 인덱스를 사용하여 액세스 할 수 있습니다std::get<INDEX>(tuple_object)
for 루프 본문 내에서 객체의 별칭을 쉽게 지정할 수 있지만 여전히 for .first
또는 std::get
루프 조건 및 업데이트 식 을 사용해야 합니다.
for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
std::get<0>(t) < 10;
++std::get<0>(t)) {
auto& i = std::get<0>(t);
auto& s = std::get<1>(t);
auto& v = std::get<2>(t);
std::cout << s << std::endl; // cout Hello world
v.push_back(i); // add counter value to the vector
}
C ++ 98 및 C ++ 03 의 유형 이름을 명시 적으로 지정할 수 있습니다 std::pair
. 그러나 이것을 두 가지 이상의 유형으로 일반화하는 표준 방법은 없습니다.
for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
std::cout << p.second << std::endl;
}
make_
and를 삭제할 수도 있습니다 std::pair(1, 1.0)
.
아니요-그러나 기술적으로 해결 방법이 있습니다 (강제하지 않으면 실제로 사용하지는 않습니다).
for(struct { int a; char b; } s = { 0, 'a' } ; s.a < 5 ; ++s.a)
{
std::cout << s.a << " " << s.b << std::endl;
}
struct { int a=0; char b='a'; } s;
불가능하지만 다음을 수행 할 수 있습니다.
float f;
int i;
for (i = 0,f = 0.0; i < 5; i++)
{
//...
}
또는 명시 적으로 범위 제한 f
및 i
추가 괄호를 사용하여 :
{
float f;
int i;
for (i = 0,f = 0.0; i < 5; i++)
{
//...
}
}
최선의 접근 방식은 xian의 대답 이라고 생각 합니다.
그러나...
이 방법은 더럽지 만 모든 버전에서 해결할 수 있습니다.
그래서 종종 매크로 함수에서 사용합니다.
for(int _int=0, /* make local variable */ \
loopOnce=true; loopOnce==true; loopOnce=false)
for(char _char=0; _char<3; _char++)
{
// do anything with
// _int, _char
}
declare local variables
및에 사용할 수도 있습니다 initialize global variables
.
float globalFloat;
for(int localInt=0, /* decalre local variable */ \
_=1;_;_=0)
for(globalFloat=2.f; localInt<3; localInt++) /* initialize global variable */
{
// do.
}
좋은 예 : 매크로 기능 사용.
( for-loop-macro이므로 최상의 접근 방식을 사용할 수없는 경우 )
#define for_two_decl(_decl_1, _decl_2, cond, incr) \
for(_decl_1, _=1;_;_=0)\
for(_decl_2; (cond); (incr))
for_two_decl(int i=0, char c=0, i<3, i++)
{
// your body with
// i, c
}
if (A* a=nullptr);
else
for(...) // a is visible
0
또는로 초기화 nullptr
하려면이 트릭을 사용할 수 있습니다.
그러나 나는 열심히 읽는 때문에 이것을 권장하지 않습니다.
그리고 버그처럼 보입니다.
다중 for 루프 중첩과 관련된 다른 방법은 "for 루프에서 두 유형의 변수를 정의하는 방법이 있습니까? "를 참조하십시오 . Georg의 "struct trick"에 비해 다른 방법의 장점은 (1) 정적 및 비 정적 로컬 변수를 혼합 할 수 있고 (2) 복사 할 수없는 변수를 가질 수 있다는 것입니다. 단점은 읽기가 훨씬 적고 효율성이 떨어질 수 있다는 것입니다.
매크로를 정의하십시오.
#define FOR( typeX,x,valueX, typeY,y,valueY, condition, increments) typeX x; typeY y; for(x=valueX,y=valueY;condition;increments)
FOR(int,i,0, int,f,0.0, i < 5, i++)
{
//...
}
변수 범위도 이런 식으로 for 루프 내에 있지 않습니다.
{
and를 사용하여 매크로의 코드를 별도의 범위로 줄임으로써 이러한 제한을 쉽게 극복 할 수 있습니다 }
.
-std=c++0x
) 형식은for(auto i=0, j=0.0; ...
가능하지만 g ++-4.5에서는 c ++ 0x 텍스트와 일치하도록이 가능성이 제거되었습니다.