这是“与”进行“合作”的最佳方式吗? C++ 中的语句?

发布于 2024-09-30 07:58:08 字数 1793 浏览 7 评论 0原文

编辑:

所以这个问题被误解到了如此荒谬的程度,以至于它不再有任何意义了。我不知道如何,因为我实际上的问题是我的具体实现是否是的,已知是没有意义的,是的,与惯用的 C++ 完全不同——宏已经尽可能好了,而且无论它是否必须使用 auto,或者是否有合适的解决方法。它不应该引起如此多的关注,当然也不应该引起如此严重的误解。要求受访者编辑他们的答案是毫无意义的,我不希望任何人因此而失去声誉,并且这里为未来潜在的观众提供了一些很好的信息,所以我将任意选择一个得票率较低的人答案以平均分配所涉及的声誉。继续走吧,这里没什么可看的。


我看到这个问题并决定编写一个可能会很有趣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 因为它是一个不常见的标识符,而且它的形式给人一种“通用事物”的印象。如果您有更好的标识符或更可用的语法的想法,请提出建议。

Edit:

So this question was misinterpreted to such a ludicrous degree that it has no point anymore. I don't know how, since the question that I actually asked was whether my specific implementation of this—yes, known to be pointless, yes, not remotely resembling idiomatic C++—macro was as good as it could be, and whether it necessarily had to use auto, or if there was a suitable workaround instead. It was not supposed to generate this much attention, and certainly not a misunderstanding of this magnitude. It's pointless to ask respondents to edit their answers, I don't want anybody to lose reputation over this, and there's some good information floating around in here for potential future viewers, so I'm going to arbitrarily pick one of the lower-voted answers to evenly distribute the reputation involved. Move along, nothing to see here.


I saw this question and decided it might be fun to write a with statement in C++. The auto keyword makes this really easy, but is there a better way to do it, perhaps without using auto? I've elided certain bits of the code for brevity.

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)

Here's an (updated) usage example with a more typical case that shows the use of with as it is found in other languages.

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;

}

I chose o because it's an uncommon identifier, and its form gives the impression of a "generic thing". If you've got an idea for a better identifier or a more usable syntax altogether, then please do suggest it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寒冷纷飞旳雪 2024-10-07 07:58:08

如果您使用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);
    }
}

If you use auto, why use macros at all?

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

EDIT: Without auto, just use typedef and references.

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);
    }
}
只有影子陪我不离不弃 2024-10-07 07:58:08

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

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

with(a)
 .do
 .domore
 .doitall

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

对我来说,为什么使用 with where multiple dereferences

so 而不是

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

?? attempted vb syntax into C++

with says do all the things in the following block by default referencing the object I've said to do it with right? Executes a series of statements making repeated reference to a single object or structure.

with(a)
 .do
 .domore
 .doitall

so how is the example giving you the same syntax?

to me examples of why to use a with where multiple de referencess

so rather than

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

you have

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

seems just as easy, and more common syntax in C++ to

cell& c = book.sheet.table.col(a).row(2);
c.setColour
c.setFont
c.setText
c.setBorder
桃气十足 2024-10-07 07:58:08

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

    }
}

For C++0x (which you're assuming):

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

    }
}
要走干脆点 2024-10-07 07:58:08

为什么不直接使用一个好的 lambda 呢?

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

一个简单的事实是,如果您的标识符太长,您无法每次都输入它们,请使用引用、函数、指针等来解决此问题,或者更好的是重构名称。像这样的语句(例如 C# 中的 using())具有额外的副作用(在我的示例中是确定性清理)。您在 C++ 中的语句没有显着的实际好处,因为它实际上不会调用任何针对仅编写代码的附加行为。

Why not just use a good lambda?

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

The simple fact is that if your identifiers are so long, that you can't type them out every time, use a reference, function, pointer, etc to solve this problem, or better, refactor the name. Statements like this (e.g. using() in C#) have additional side effects (deterministic cleanup, in my example). Your statement in C++ has no notable actual benefits, since it doesn't actually invoke any additional behaviour against just writing the code out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文