Does C++ have "with" keyword like Pascal?

21,169

Solution 1

In C++, you can put code in a method of the class being reference by pointer. There you can directly reference the members without using the pointer. Make it inline and you pretty much get what you want.

Solution 2

Probably the closest you can get is this: (this is just an academic exercise. Of course, you can't use any local variables in the body of these artificial with blocks!)

struct Bar {
    int field;
};

void foo( Bar &b ) {
    struct withbar : Bar { void operator()() {
        cerr << field << endl;
    }}; static_cast<withbar&>(b)();
}

Or, a bit more demonically,

#define WITH(T) do { struct WITH : T { void operator()() {
#define ENDWITH(X) }}; static_cast<WITH&>((X))(); } while(0)

struct Bar {
    int field;
};

void foo( Bar &b ) {
    if ( 1+1 == 2 )
        WITH( Bar )
            cerr << field << endl;
        ENDWITH( b );
}

or in C++0x

#define WITH(X) do { auto P = &X; \
 struct WITH : typename decay< decltype(X) >::type { void operator()() {
#define ENDWITH }}; static_cast<WITH&>((*P))(); } while(0)

        WITH( b )
            cerr << field << endl;
        ENDWITH;

Solution 3

no there is no such keyword.

Solution 4

I like to use:

    #define BEGIN_WITH(x) { \
        auto &_ = x;

    #define END_WITH() }

Example:

    BEGIN_WITH(MyStructABC)
    _.a = 1;
    _.b = 2;
    _.c = 3;
    END_WITH()

Solution 5

Even though I program mostly in Delphi which has a with keyword (since Delphi is a Pascal derivative), I don't use with. As others have said: it saves a bit on typing, but reading is made harder.

In a case like the code below it might be tempting to use with:

cxGrid.DBTableView.ViewData.Records.FieldByName('foo').Value = 1;
cxGrid.DBTableView.ViewData.Records.FieldByName('bar').Value = 2;
cxGrid.DBTableView.ViewData.Records.FieldByName('baz').Value = 3;

Using with this looks like this

with cxGrid.DBTableView.ViewData.Records do
begin
  FieldByName('foo').Value = 1;
  FieldByName('bar').Value = 2;
  FieldByName('baz').Value = 3;
end;

I prefer to use a different technique by introducing an extra variable pointing to the same thing with would be pointing to. Like this:

var lRecords: TDataSet;

lRecords := cxGrid.DBTableView.ViewData.Records;

lRecords.FieldByName('foo').Value = 1;
lRecords.FieldByName('bar').Value = 2;
lRecords.FieldByName('baz').Value = 3;

This way there is no ambiguity, you save a bit on typing and the intent of the code is clearer than using with

Share:
21,169

Related videos on Youtube

Shog9
Author by

Shog9

Well, fancy seeing you here! I work for EDB, assisting a bunch of really skilled people share their PostgreSQL expertise and experience with the world. Before that, I worked here - at Stack Overflow / Stack Exchange. Here, my duties also involved helping a bunch of really skilled people share their knowledge. So you might encounter some posts from me which provide guidance and advice for the folks using this network of Q&amp;A sites. I tend to write as though I know what I'm writing about... And sometimes I do... But, you should always use your own judgement: question everything, read the links to supporting materials, and draw your own conclusions. I'm usually happy to discuss anything I've written, so don't hesitate to raise concerns or point out when something is unclear! Whatsoever thy hand findeth to do, do it with thy might; for there is no work, nor device, nor knowledge, nor wisdom, in the grave, whither thou goest.

Updated on July 09, 2022

Comments

  • Shog9
    Shog9 almost 2 years

    with keyword in Pascal can be use to quick access the field of a record. Anybody knows if C++ has anything similar to that?

    Ex: I have a pointer with many fields and i don't want to type like this:

    if (pointer->field1) && (pointer->field2) && ... (pointer->fieldn)
    

    what I really want is something like this in C++:

    with (pointer)
    {
      if (field1) && (field2) && .......(fieldn)
    }
    
    • Ben Zotto
      Ben Zotto about 14 years
      Huh. Javascript has the with keyword and it does substantially the same thing; I didn't realize it had a pedigree reaching back to Pascal (!).
    • Svetlozar Angelov
      Svetlozar Angelov about 14 years
      Maybe it comes from Cobol or ADA, who knows...
    • AProgrammer
      AProgrammer about 14 years
      There is a with in Ada, but not with that meaning.
    • Ignacio Soler Garcia
      Ignacio Soler Garcia about 14 years
      There is a with in Vb and in Vb.Net with the same meaning too.
    • erikkallen
      erikkallen about 14 years
      But in VB you need to say With obj / .X = x, so it's not as ambiguous
  • Marco van de Voort
    Marco van de Voort about 14 years
    There is always the question that if something can be abused, means that it is bad.
  • Ankit Roy
    Ankit Roy about 14 years
    Sure, because name lookup in C++ is so straightforward. No -1, but I think the "can make code ambiguous" argument falls flat when you consider the case of argument-dependent lookup for functions, especially for instantiations of function templates.
  • Ankit Roy
    Ankit Roy about 14 years
    This strategy works with C++ too, using a local T& or T const& variable to hold a reference to the long expression (which must be a proper lvalue in the T& case). To make it visually stand out, I usually name the variable _.
  • Chris Walton
    Chris Walton about 14 years
    Very nice :). I'd like to mention though that for those few of us that work with the Metrowerks compiler, this is quite likely not to work (it doesn't deal well with structs in a function)
  • Potatoswatter
    Potatoswatter about 14 years
    @arke: really? That's surprising, I loved Metrowerks when it was the Mac standard. Hmm, it looks like they lost Howard Hinnant…
  • karkael
    karkael about 14 years
    I agree it can be useful but I've seen it abused so many times now that I stay away from using it. In particular it can bite you if field1 is renamed in the record so your with-code now suddenly silently refers to another variable in scope with the same name. Instead of with I use one of the other approaches suggested here: use a local variable with short name or move it to a function/method.
  • Nikola Gedelovski
    Nikola Gedelovski about 14 years
    Upvote. The worst language feature. Consider this abomination: with struct1, struct2.substruct3, struct4.substruct5.ptrstruct6^... Seen it.
  • Will
    Will about 14 years
    Visual Basic tidied up the syntax by requiring the fields belonging to the 'with' to be prefixed with a "." - it also helped syntax completion etc. Our host Joel did that :)
  • Dacav
    Dacav almost 14 years
    What do you mean for “make it inline”? Can you declare the method just inside another function? It's weird...
  • Alexandre C.
    Alexandre C. almost 14 years
    you can use static variables though.
  • Steve Jessop
    Steve Jessop over 12 years
    Probably should be auto &p = *pointer, since your code takes a copy.
  • Potatoswatter
    Potatoswatter about 9 years
    @Dacav This answer is just suggesting to add a method to the class being used by with. Being inline allows it to go into a header but otherwise that's a red herring. Such a method must be declared in its original class, and defined outside any other function. My answer below has a workaround to both problems.
  • NicoBerrogorry
    NicoBerrogorry about 5 years
    This is actually sick good, because encapsulation is preserved... Thanks for making the connection!
  • Server Overflow
    Server Overflow over 4 years
    Not dangerous if you apply it only on a single type (record, structure, object, etc). In other words, never mix objects inside the "with" and your safe.
  • Server Overflow
    Server Overflow over 4 years
    it is NOT BY FAR the same!
  • somebody4
    somebody4 almost 4 years
    In c++17, it would be better to do if(auto a=foo();true){/**/}
  • Sebastian
    Sebastian over 3 years
    This answer does not seem related to the question?