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

时间:2010-10-29 18:52:24

标签: c++ c++11 with-statement

修改

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


我看到this question并认为在C ++中编写with语句可能会很有趣。 auto关键字使这非常简单,但有没有更好的方法,也许不使用auto?为简洁起见,我省略了一些代码。

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在其他语言中的使用情况。

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] << '\n'
            << (*o)[1] << '\n'
            << (*o)[2] << '\n';

    }

    return 0;

}

我选择了o因为它是一个不常见的标识符,它的形式给人的印象是“通用的东西”。如果您对完整的标识符或更完整的语法有所了解,那么请建议。

4 个答案:

答案 0 :(得分:7)

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

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] << '\n'
            << o[1] << '\n'
            << o[2] << '\n';
    }

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

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

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);
    }
}

答案 1 :(得分:6)

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

with说默认引用下面的块中的所有内容引用我说过要做的对象吧? Executes a series of statements making repeated reference to a single object or structure.

with(a)
 .do
 .domore
 .doitall

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

向我举例说明为什么要使用多个参考文献

所以而不是

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

你有

with( book.sheet.table.col(a).row(2) )
  .setColour
  .setFont
  .setText
  .setBorder

似乎同样容易,而且在C ++中更常见的语法

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

答案 2 :(得分:3)

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

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);

    }
}

答案 3 :(得分:0)

为什么不使用好的lambda?

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

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