在for循环中声明两个不同的变量,其中一个是不可移动的,不可复制的对象

时间:2013-09-10 18:01:04

标签: c++ c++11

我知道在使用std::pair或匿名struct类型的for循环中声明和初始化两个不同的变量,但these不能用于我的目的。

假设我有以下类定义

class Object {
    private:
        int i;
    public:
        Object(int i) : i(i) { }
        // everything else deleted
        Object() = delete;
        Object(const Object &) = delete;
        Object(Object &&) = delete;
        Object & operator=(const Object &) = delete;
        Object & operator=(Object &&) = delete;
};

我是否可以在Object循环行中初始化intfor。我不想在for循环或类似的东西周围添加额外的块。我可以使用std::tuplestd::pair,匿名structs,无论如何,只要它的格式为

for(/* creates Object and int*/ ; /*whatever*/; /*whatever*/) { /* ... */}

或(如果存在语法)

for( Object o(69), int i = 0; i < 10; ++i) { /* ... */ }

我不想要的是额外的命名类定义。我已经想到了这个:

for(class Container : private Object {
            public:
                int value;
                Container(int i) : Object(i), value(0) { }
                } container(69); /* ... */ ;
        container.value < 10;
        ++container.value) { /* ... */}

但是类名Container然后在for循环中变得可见,我试图避免。

我的实际使用它是std::lock_guard<std::mutex>bool,因此在退出循环后释放互斥锁。

2 个答案:

答案 0 :(得分:6)

您可以使用piecewise construction来调用构造函数:

for (std::pair<Object, int> x (std::piecewise_construct,
                               std::make_tuple(69),
                               std::make_tuple(0));
     x.second < 10; x.second ++) {

    std::cout << x.first.i << "/" << x.second << std::endl;
    x.first.i += 4;
}

不幸的是,这并不能归结为元组。 std::tuple没有分段构造函数。


不确定为什么你会忽视它,但我发现与更直接的实现相比,“配对”解决方案非常难看

{
    Object o (69);
    for (int i = 0; i < 10; ++ i) {
        std::cout << o.i << "/" << i;
        o.i += i;
    }
}

答案 1 :(得分:1)

是的,optional

#include <utlility>

std::optional<Object> o;

for ( ; ; )
{
    o.emplace(12);
}

(这在C ++ 14中可用,但也可从<boost/optional.hpp>获得。)