关于c ++ 11:这是在C ++中执行“with”语句的最佳方法吗?

Is this the best way to do a “with” statement in C++?

编辑:

所以这个问题被误解为这样一个荒谬的程度,它已经没有意义了。我不知道怎么回事,因为我实际上问的问题是我是否具体实现了这个—是的,已知是毫无意义的,是的,不是非常类似于惯用的C ++—宏虽然可能是好的,并且是否必须使用auto,或者是否有合适的解决方法。它不应该产生这么多的关注,当然不是对这种程度的误解。要求受访者编辑他们的答案是毫无意义的,我不希望任何人因此而失去声誉,而且这里有一些好的信息可供潜在的未来观众使用,所以我将随意挑选一个较低的选民答案是均匀分配所涉及的声誉。继续前进,没有什么可看的。

我看到了这个问题并决定在C ++中编写with语句可能会很有趣。 auto关键字使这很容易,但有没有更好的方法来实现它,也许不使用auto?为简洁起见,我省略了一些代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template<class T>
struct with_helper {

    with_helper(T& v) : value(v), alive(true) {}

    T* operator->() { return &value; }
    T& operator*() { return value; }

    T& value;
    bool alive;

};


template<class T> struct with_helper<const T> { ... };


template<class T> with_helper< T >       make_with_helper(T& value) { ... }
template<class T> with_helper<const T> make_with_helper(const T& value) { ... }


#define with(value) \
for (auto o = make_with_helper(value); o.alive; o.alive = false)

这是一个(更新的)用法示例,其中一个更典型的案例显示了在其他语言中使用的with

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main(int argc, char** argv) {

    Object object;

    with (object) {

        o->member = 0;
        o->method(1);
        o->method(2);
        o->method(3);

    }

    with (object.get_property("foo").perform_task(1, 2, 3).result()) {

        std::cout
            << (*o)[0] << '
'

            << (*o)[1] << '
'

            << (*o)[2] << '
'
;

    }

    return 0;

}

我选择了o因为它是一个不常见的标识符,它的形式给人一种"通用的东西"的印象。如果你对一个更好的标识符或一个更实用的语法有了一个想法,那么请建议它。


如果你使用auto,为什么要使用宏呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int main()
{
    std::vector<int> vector_with_uncommonly_long_identifier;

    {
        auto& o = vector_with_uncommonly_long_identifier;

        o.push_back(1);
        o.push_back(2);
        o.push_back(3);
    }

    const std::vector<int> constant_duplicate_of_vector_with_uncommonly_long_identifier
        (vector_with_uncommonly_long_identifier);

    {
        const auto& o = constant_duplicate_of_vector_with_uncommonly_long_identifier;

        std::cout
            << o[0] << '
'

            << o[1] << '
'

            << o[2] << '
'
;
    }

    {
        auto o = constant_duplicate_of_vector_with_uncommonly_long_identifier.size();
        std::cout << o <<'
'
;
    }
}

编辑:没有auto,只需使用typedef和引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    typedef std::vector<int> Vec;

    Vec vector_with_uncommonly_long_identifier;

    {
        Vec& o = vector_with_uncommonly_long_identifier;

        o.push_back(1);
        o.push_back(2);
        o.push_back(3);
    }
}


??尝试将vb语法转换为C ++

with表示默认情况下会执行以下块中的所有操作来引用我说过要做的对象吗?执行一系列语句,重复引用单个对象或结构。

1
2
3
4
with(a)
 .do
 .domore
 .doitall

那么该示例如何为您提供相同的语法?

向我举例说明为什么要使用多个de引用的地方

所以而不是

1
2
3
4
book.sheet.table.col(a).row(2).setColour
book.sheet.table.col(a).row(2).setFont
book.sheet.table.col(a).row(2).setText
book.sheet.table.col(a).row(2).setBorder

你有

1
2
3
4
5
with( book.sheet.table.col(a).row(2) )
  .setColour
  .setFont
  .setText
  .setBorder

看起来就像在C ++中一样简单,也是更常见的语法

1
2
3
4
5
cell& c = book.sheet.table.col(a).row(2);
c.setColour
c.setFont
c.setText
c.setBorder


对于C ++ 0x(您假设):

1
2
3
4
5
6
7
8
9
10
11
12
13
int main() {

    std::vector<int> vector_with_uncommonly_long_identifier;

    {
        auto& o = vector_with_uncommonly_long_identifier;

        o.push_back(1);
        o.push_back(2);
        o.push_back(3);

    }
}


为什么不用一个好的lambda?

1
2
3
auto func = [&](std::vector<int>& o) {
};
func(vector_with_a_truly_ridiculously_long_identifier);

简单的事实是,如果你的标识符太长,你不能每次输出它们,使用引用,函数,指针等来解决这个问题,或者更好,重构名称。像这样的语句(例如在C#中使用())会产生额外的副作用(在我的例子中,确定性清理)。你在C ++中的声明没有显着的实际好处,因为它实际上不会调用任何额外的行为来反对编写代码。