Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;11无循环变量的循环基于范围 在C++中,我需要迭代一定次数,但不需要迭代变量。例如: for( int x=0; x<10; ++x ) { /* code goes here, i do not reference "x" in this code */ }_C++_C++11 - Fatal编程技术网

C++;11无循环变量的循环基于范围 在C++中,我需要迭代一定次数,但不需要迭代变量。例如: for( int x=0; x<10; ++x ) { /* code goes here, i do not reference "x" in this code */ }

C++;11无循环变量的循环基于范围 在C++中,我需要迭代一定次数,但不需要迭代变量。例如: for( int x=0; x<10; ++x ) { /* code goes here, i do not reference "x" in this code */ },c++,c++11,C++,C++11,但是上面给出了一个“未引用的局部变量”,因为我从来没有明确引用过x 我想知道是否有一种更优雅的方法来编写上述for循环,这样代码就不会生成“未引用的局部变量”警告。可能有一种方法可以做到这一点,但我非常怀疑它是否更优雅。第一个循环中的内容已经是正确的方法,限制了循环变量的作用域/生命周期 我只会忽略未使用的变量警告(毕竟,这只是编译器可能出错的指示),或者使用编译器工具(如果可用)简单地在该点关闭警告 根据您的环境,使用某种类型的#pragma,或者某些实现允许您执行以下操作: for (int

但是上面给出了一个“未引用的局部变量”,因为我从来没有明确引用过x


我想知道是否有一种更优雅的方法来编写上述for循环,这样代码就不会生成“未引用的局部变量”警告。

可能有一种方法可以做到这一点,但我非常怀疑它是否更优雅。第一个循环中的内容已经是正确的方法,限制了循环变量的作用域/生命周期

我只会忽略未使用的变量警告(毕竟,这只是编译器可能出错的指示),或者使用编译器工具(如果可用)简单地在该点关闭警告

根据您的环境,使用某种类型的
#pragma
,或者某些实现允许您执行以下操作:

for (int x = 0; x < 10; ++x) {
    (void)x;

    // Other code goes here, that does not reference "x".
}
for(int x=0;x<10;++x){
(无效)x;
//其他代码在这里,不引用“x”。
}

我已经看到了
void
技巧用于函数体中未使用的参数。

现在编辑,声明的循环变量减少了100%

template <typename F>
void repeat(unsigned n, F f) {
    while (n--) f();
}


假设
10
是一个编译时常量,请查看它live at

#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();
  });
}
它使用了一个变量(
\uu
),但看起来非常混乱

另一个疯狂的方法是创建一个类似python的生成器。编写一个生成器包装器,它接受一个iterable范围并生成一个函数,该函数在该范围的
value\u type
上返回
std::optional

我们可以这样做:

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);
  }
}
但是这在函数中创建了一些临时变量,比上一个更荒谬,并且依赖于C++1y的特性,而C++1y甚至还没有最终确定

我试图创建一个变量较少的方法来重复10次

但事实上,我只是做循环

您几乎可以通过键入
x=x来阻止警告

或者写一个函数

template<typename Unused>
void unused( Unused&& ) {}

这应该会抑制警告,并且实际上很容易理解。

没有任何方法可以简单地对几个数字进行迭代,从而创建基于范围的工作

C++11基于范围的循环需要一个范围表达式,该表达式可能是:

  • 数组或
  • 有两个或两个的班级
    • 成员函数
      begin()
      end()
    • 可用的免费函数
      begin()
      end()
      (通过ADL)
除此之外:基于的范围会产生一些开销:

for ( for_range_declaration : expression ) statement
扩展到

range_init = (expression)
{
  auto && __range = range_init;
  for ( auto __begin = begin_expr,
  __end = end_expr;
  __begin != __end;
  ++__begin ) {
    for_range_declaration = *__begin;
    statement;
  }
}
其中,begin_expr和end_expr是通过阵列检查或
begin()
/
end()
对获得的

我不认为这比一个简单的for循环更“干净”。特别是在性能方面。 没有呼叫,只是一个简单的循环

我能想出的使其更优雅的唯一方法(优雅显然取决于我的意见)是在此处使用大小或无符号类型:

for(size_t x(0U); x<10U; ++x) f();

for(size_t x(0U);x实际上有一种方法可以实现这一点。您只需返回一个
std::array
,其长度由您提供的常量指定:

template <int N>
using range = std::array<int, N>;

int main()
{
    for (auto x : range<5>())
    {
        std::cout << "Awesome\n";
    }
}
模板
使用range=std::array;
int main()
{
对于(自动x:range())
{

std::cout在我看来,您误用了基于范围的循环。当逻辑为“对于集合中的每个元素,请执行某些操作”时,应使用基于范围的循环。因为索引变量并不重要,所以整个想法是去掉它。如果你有一个集合,你应该用必要的API对它进行检测,以启用基于范围的迭代。如果你没有集合,你就没有必要使用基于范围的循环(事实上,这是编译器在信息量不大的情况下暗示的)。在这种情况下,正常的for/while循环是自然选择。

您可以将STL与lambda表达式一起使用

#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;});
}
#包括
#包括
int main(){
int a[]={1,2,3,4,5,6};
标准::对于每个(标准::开始(a),
标准::结束(a),

[](int){std::cout中已经给出了最好的答案:如何定义在整个代码库中使用的未使用的宏,这将抑制此警告。以可移植的方式。

这适用于GCC和clang以及任何支持gnu属性的编译器:

for( [[gnu::unused]] auto x : boost::irange(0,10) ) {
并且应该在任何c++11编译器中编译,但如果编译器无法识别gnu属性,则可能不会抑制警告。

要参加竞赛:

#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;
}
#包括
#包括
使用名称空间std;
使用名称空间boost;
名称空间{
模板内联空
未使用(常数T&){}
}
int main(){
用于(自动和输入:irange(0,10)){
未使用(i);

为了澄清这一点,我的解释是OP正在尝试使用基于范围的for循环来执行此操作。但是,类似于
for(auto x:boost::irange(0,10))f();
将发出警告,因为
x
未使用。但是变量被引用(在循环条件下)。编译器绝对不应该对该代码发出警告。@rodrigo:我不这么认为,循环条件使用了隐藏的迭代器。
x
被写入但从未读取,导致编译器发出警告。@MooingDuck
x@Yakk:
for(自动x:boost::irange(0,10))
不包含表达式
xWhy is 1 special cased?似乎没有必要为什么所有的模板都是魔法?我的答案是3行,并且还将编译为编译时常量
n
…(最近在gcc/clang上验证)@谁信任优化器?但说真的,OP要求消除循环变量:所以我认真对待OP。实际上,你应该支持它
template<typename Unused>
void unused( Unused&& ) {}
for(int x{};x<10;++x) {
  unused(x);
  f();
}
for ( for_range_declaration : expression ) statement
range_init = (expression)
{
  auto && __range = range_init;
  for ( auto __begin = begin_expr,
  __end = end_expr;
  __begin != __end;
  ++__begin ) {
    for_range_declaration = *__begin;
    statement;
  }
}
for(size_t x(0U); x<10U; ++x) f();
template <int N>
using range = std::array<int, N>;

int main()
{
    for (auto x : range<5>())
    {
        std::cout << "Awesome\n";
    }
}
#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;});
}
for( [[gnu::unused]] auto x : boost::irange(0,10) ) {
#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;
}