很简单,是否有一种更简单的方法可以将某个块重复一定次数,而其中的块不需要计数器变量?平凡的解决方案当然是
for (int i = 0; i < repetitions; ++i) {
//do your thing, i is not used here
}
但是,既然我们已经找到了用于遍历容器的标准算法和其他奇特的构造,那么相比之下,这实际上开始感觉像是很多样板和细节,甚至应该是更简单的情况。例如,我们对变量i
完全不感兴趣,等等。
与具体问题最接近的事情是:当我遇到上述的for循环时,我需要遍历代码块以查看是否实际使用i
,或者它只是一个虚拟计数器。 。 for循环的声明实际上想要用0到repetitions - 1
的整数来表示,这看起来是相同的。因此,repeat (n)
型构造将具有额外的语义信息,除了潜在的副作用外,所有迭代都将是相同的。
一种选择是制作模板
template<class functor>
repeat(functor fun, unsigned n) {
for (unsigned i = 0; i < n; ++i)
fun();
}
并致电
repeat([&](){
//do your thing
}, repetitions)
但是对于一个简单的问题,这似乎确实是过度设计的过度杀伤力。可以对它进行宏化处理,以使其使用起来更好一些,但是对于过度设计的感觉当然不会有所帮助。
一个有效的答案是,我在这里追逐野鹅,应该使用带有计数器的好for循环。
任何标准C ++都可以,包括即将发布的标准。
诸如How to create a loop in C++ that loops a certain amount of times?和How to create a loop in C++ that loops a certain amount of times?之类的相关问题是初学者,他们要求某种方式来实现这一目标,而我特别要求一种现代,干净且优雅的方式来实现这一目标。 c++ repeat N iterations非常接近,尽管这里的区别在于我要求的是任何其他替代品,不一定包含在std::
中。
答案 0 :(得分:3)
代替现代的C ++方式,如何使用旧的C方式却没有索引:
while (repetitions--)
fun();
当然,repetitions
仍然需要一个变量。
答案 1 :(得分:1)
现代不一定意味着要使用最新功能。
最简单的解决方案之一是使用简单的for
循环,如下所示:
for (auto _ = times; _--;) [[likely]] statement;
…其中:
times
是不带后缀( ie 3)的常量integer literal。statement
是statement,将执行times
次。用法示例:
constexpr auto f(int Value) noexcept
{
for (auto _ = 3; _--;) [[likely]] ++Value;
return Value;
}
int main()
{
constexpr auto i = f(2);
return i;
}
常量i
声明为初始值2
,在f
的{{1}}循环中加3倍,取最终值{{1} },并用作程序的返回值。
[[likely]]
属性。for
常数很可能为零,请改用5
属性。times
名称通常无意义地用于命名可丢弃变量。答案 2 :(得分:0)
“手工制作” repeat
有点问题。应该有break
或continue
吗?可以从“内部”重传和“爆发”中引发异常。但是某些项目确实不允许例外。
在存在标准for range loop
的情况下,也不需要“ 扫描代码块以查看i是否实际使用,或者它只是一个虚拟计数器。” 。该论点是用完的。
拥有内置的编译器repeat
可能不是一个坏主意,并且肯定很容易添加。
// C++ 25 -- perhaps
repeat( 42 ) {
std::printf("\nThis is 42 lines of text.");
continue; // allowed
break ; // allowed
}
REPEAT(N)宏很吸引人,但是禁止使用宏。如果不是编译器固有的,则用户定义的repeat
并非“简单而优雅”。这是我可能正在使用的:
// the repeat
template< typename CALLABLE_, typename ... Args >
void repeat( size_t N, CALLABLE_ fun_, Args ... args)
{
for ( auto k = 0 ; k < N ; k++ ) {
fun_(args ...);
}
}
现在使用以上代码很可能将其称为lambda。使用情况符合预期:
// reachable from inside `repeat`
int result {} ;
repeat( 0xF ,
[&] {
::std::wprintf( L"\n random word:\t '%s'", random_word());
result++ ;
}
);
“现代方式”并不总是“优雅的复古方式”。