루프 변수가없는 C ++ 11 범위 기반 for 루프
C ++에서는 특정 횟수만큼 반복해야하지만 반복 변수는 필요하지 않습니다. 예를 들면 :
for( int x=0; x<10; ++x ) {
/* code goes here, i do not reference "x" in this code */
}
"code goes here"를 람다 또는 명명 된 함수로 대체하여이 작업을 수행 할 수 있다는 것을 알고 있지만이 질문은 특히 for 루프에 관한 것입니다.
C ++ 11의 범위 기반 for 루프가 도움이되기를 바라고 있습니다.
for( auto x : boost::irange(0,10) ) {
/* code goes here, i do not reference "x" in this code */
}
그러나 위는 명시 적으로 x를 참조하지 않기 때문에 "참조되지 않은 지역 변수"를 제공합니다.
코드가 "참조되지 않은 지역 변수"경고를 생성하지 않도록 위의 for 루프를 작성하는 더 우아한 방법이 있는지 궁금합니다.
이 그것을 할 수있는 방법이 될 수 있지만 수 있습니다 매우 훨씬 더 우아한 것 의심한다. 그 첫 번째 루프에있는 것은 이미 루프 변수의 범위 / 수명을 제한하는 올바른 방법입니다.
사용하지 않는 변수 경고를 무시하거나 (결국 문제 가있을 수 있다는 컴파일러의 표시 일뿐 ) 컴파일러 기능 (사용 가능한 경우)을 사용하여 해당 시점에서 경고를 해제합니다.
이것은 #pragma
환경 에 따라 어떤 종류의 경우 가능할 수 있으며 일부 구현에서는 다음과 같은 작업을 수행 할 수 있습니다.
for (int x = 0; x < 10; ++x) {
(void)x;
// Other code goes here, that does not reference "x".
}
void
함수 본문에서 사용되지 않는 매개 변수에 사용되는 트릭을 보았습니다 .
선언 된 루프 변수를 100 % 줄여 지금 편집하십시오 .
template <typename F>
void repeat(unsigned n, F f) {
while (n--) f();
}
다음과 같이 사용하십시오.
repeat(10, f);
또는
repeat(10, [] { f(); });
또는
int g(int);
repeat(10, std::bind(g, 42));
이보기 에 살고 http://ideone.com/4k83TJ
10
컴파일 시간 상수 라고 가정하면 ...
#include <cstddef>
#include <utility>
template<std::size_t N>
struct do_N_times_type {
template<typename Lambda>
void operator()( Lambda&& closure ) const {
closure();
do_N_times_type<N-1>()(std::forward<Lambda>(closure));
}
};
template<>
struct do_N_times_type<1> {
template<typename Lambda>
void operator()( Lambda&& closure ) const {
std::forward<Lambda>(closure)();
}
};
template<>
struct do_N_times_type<0> {
template<typename Lambda>
void operator()( Lambda&& closure ) const {
}
};
template<std::size_t N, typename Lambda>
void do_N_times( Lambda&& closure ) {
do_N_times_type<N>()( std::forward<Lambda>(closure) );
};
#include <iostream>
void f() {
std::cout << "did it!\n";
}
int main() {
do_N_times<10>([&]{
f();
});
}
아니면 그냥
int main() {
do_N_times<10>(f);
}
다른 우스꽝스러운 방법 :
index
적분에 대한 반복 유형의 범위를 생성 하는 범위 반복기 (내가 호출 함 )를 작성합니다 (기본값은 std::size_t
). 그런 다음 다음을 입력하십시오.
for( auto _:index_range(10) )
변수 ( _
) 를 사용 하지만 매우 혼란스러워 보입니다.
또 다른 미친 접근법은 파이썬과 유사한 생성기를 만드는 것입니다. 반복 가능 범위를 취하고 반환하는 함수를 생산하는 발전기 래퍼 작성 std::optional
상의 value_type
범위가 까다로운되지 않습니다.
그러면 다음을 수행 할 수 있습니다.
auto _ = make_generator( index_range(10) );
while(_()) {
}
임시 변수도 생성하고 더욱 둔감합니다.
생성기에서 작동하는 루핑 함수를 작성할 수 있습니다.
template<typename Generator, typename Lambda>
void While( Generator&& g, Lambda&& l ) {
while(true) {
auto opt = g();
if (!opt) return;
l(*opt);
}
}
다음과 같이 호출합니다.
While( make_generator( index_range(10) ), [&](auto&&){
f();
});
그러나 이것은 둘 다 함수에 임시 변수를 생성하고 마지막 것보다 더 우스꽝스럽고 마무리조차되지 않은 C ++ 1y의 기능에 의존합니다.
내가 무언가를 10 번 반복하는 변수없는 방법을 만들려고하는 것.
하지만 실제로는 루프를 수행 할 것입니다.
거의 확실하게 다음을 입력하여 경고를 차단할 수 있습니다. x=x;
또는 함수 작성
template<typename Unused>
void unused( Unused&& ) {}
그리고 호출 unused(x);
-변수 x
가 사용되고 그 이름이 내부에 삭제되므로 컴파일러가 내부에 대해 경고하지 않을 수 있습니다.
그래서 이것을 시도하십시오 :
template<typename Unused>
void unused( Unused&& ) {}
for(int x{};x<10;++x) {
unused(x);
f();
}
경고를 억제하고 실제로 이해하기 쉽습니다.
실제로이 작업을 수행하는 방법이 있습니다. 당신이해야 할 일은 std::array
당신이 제공 한 상수에 의해 지정된 길이를 반환하는 것입니다 :
template <int N>
using range = std::array<int, N>;
int main()
{
for (auto x : range<5>())
{
std::cout << "Awesome\n";
}
}
산출:
굉장
굉장
굉장
굉장
굉장
Note: This is assuming the range specifier is a compile-time constant, so if you have to use a variable make sure it is validly marked constexpr
.
There isn't any way to make a range based for work for simply iterating over several numbers.
C++11 range-based loops require a ranged expression which may be:
- an array or
- a class having either
- Member functions
begin()
andend()
or - available free functions
begin()
andend()
(via ADL)
- Member functions
In addition to that: A range based for produces some overhead:
for ( for_range_declaration : expression ) statement
expands to
range_init = (expression)
{
auto && __range = range_init;
for ( auto __begin = begin_expr,
__end = end_expr;
__begin != __end;
++__begin ) {
for_range_declaration = *__begin;
statement;
}
}
Where begin_expr and end_expr are obtained via array inspection or begin()
/ end()
pairs.
I don't think this gets any "cleaner" than a simple for-loop. Especially with respect to performance. No calls, just a plain loop.
The only way I can figure out to make it more elegant (where elegant is clearly subject to my opinion) is by using a size or unsigned type here:
for(size_t x(0U); x<10U; ++x) f();
In my opinion you misuse the range-based loop. The range-based loop should be used when the logic is: "for each element in the collection do something". The whole idea is to get rid of the index variable since it isn't important. If you have a collection, you should instrument it with the necessary APIs to enable range-based iteration. If you don't have a collection, you have no business to use range-based loop (actually, that's what the compiler implies in not-so-informative way). In this situation a normal for/while loop is the natural choice.
Already best answered in https://stackoverflow.com/a/21800058/1147505 : how to define an UNUSED macro to be used throughout your codebase, which suppresses this warning. In a portable way.
You could use the STL together with a lambda expression.
#include <algorithm>
#include <iostream>
int main() {
int a[] = {1,2,3,4,5,6};
std::for_each(std::begin(a),
std::end(a),
[](int){std::cout << "Don't care" << std::endl;});
}
This approach also works for arbitrary containers such as vectors or lists. Let vector<int> a
, then you'd call a.begin()
and a.end()
. Note that you can also use a function pointer instead of a lambda expression.
The above preserves your notion of using a foreach, while not complaining about an unused parameter.
this works in GCC and clang and any compiler that supports the gnu attributes:
for( [[gnu::unused]] auto x : boost::irange(0,10) ) {
and should compile in any c++11 compiler but may not suppress the warning if the compiler doesn't recognise the gnu attributes.
To join the contest:
#include <iostream>
#include <boost/range/irange.hpp>
using namespace std;
using namespace boost;
namespace {
template<typename T> inline void
unused(const T&) {}
}
int main() {
for (auto&& i : irange(0,10)) {
unused(i);
cout << "Something" << endl;
}
return 0;
}
ReferenceURL : https://stackoverflow.com/questions/17711655/c11-range-based-for-loops-without-loop-variable
'IT Share you' 카테고리의 다른 글
jQuery 클릭 이벤트에서 false 반환 (0) | 2021.01.07 |
---|---|
angularjs-ng-src 내에서 {{}} 바인딩을 사용하지만 ng-src가로드되지 않음 (0) | 2021.01.07 |
Haskell의 DataKinds 확장은 무엇입니까? (0) | 2021.01.07 |
Asp.Net Identity DataBase 첫 번째 접근 방식 사용 (0) | 2021.01.07 |
제네릭 메서드는 어디에 저장됩니까? (0) | 2021.01.07 |