質問

with キーワードパスカルが利用できるクイックアクセスの分野です。誰もが知っている場合C++いても同様。

Ex:私のポインタは多くの分野ならないようにしたいタイプのようになります:

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

えていきたいと思っておりますがこのようになっC++:

with (pointer)
{
  if (field1) && (field2) && .......(fieldn)
}
役に立ちましたか?

解決

C ++では、あなたはpointerによってクラスビーイング参照の方法でコードを置くことができます。そこには、直接ポインタを使用せずにメンバを参照することができます。それはinline作成し、あなたが望むものをほとんど取得します。

他のヒント

おそらくあなたが得ることができる最も近いがこれである:(。!私をdownvoteしないでください。これは単なる学術的運動ですもちろん、あなたがこれらの人工withブロックの本体内の任意のローカル変数を使用することはできません)

struct Bar {
    int field;
};

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

それとも、もう少し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 );
}

または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;

いいえそのようなキーワードはありません。

私が使用したい:

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

    #define END_WITH() }

例:

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

私は主に(Delphiはパスカル誘導体であるため)withキーワードを持つDelphiでプログラミングするにもかかわらず、私はwithを使用しないでください。 。他の人が言ったように:それはタイピングのビットを保存しますが、読み取りが困難に作られている。

それ以下のコードのような場合に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;

これは次のようになりますwithを使用して

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

私はwithがポイントされるのと同じ事に余分な変数ポインティングを導入することにより、異なる技術を使用することを好みます。このように:

var lRecords: TDataSet;

lRecords := cxGrid.DBTableView.ViewData.Records;

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

この方法が不明確ではない場合、あなたはタイピングにビットを保存し、コードの意図は、

withを使用するよりも明確です

いいえ、C ++は、このようなキーワードを持っていません。

C ++はそのような機能を持っていません。そして、多くはフィールド1がポインタまたはローカル変数または何か他のメンバーである場合、たとえば、それは難しい知っていることは、読んでコードがあいまいとハード作ることができるため、問題であることをパスカルの「WITH」を検討してください。パスカルも付き、変数、このようなことがさらに困難になり、「VAR1、VAR2と」など、複数のことができます。

あなたが得ることができる最も近いです方法のチェーン化:

myObj->setX(x)
     ->setY(y)
     ->setZ(z)

名前空間のための複数のフィールドとusingを設定する。

with (OBJECT) {CODE}

C ++にはそのようなことはありません。
あなたは、オブジェクトのメソッドの中にあるが、それは必ずしも望ましいことではないように、コードを置くことができます。

C ++ 11を使用すると、オブジェクトの短い名前のエイリアスを作成することで、非常に近くに取得することができます。
サンプルコードは、問題の特定のために、それはそうのようになります。

{
    auto &_ = *pointer;
    if (_.field1 && ... && _.fieldn) {...}
}

(周囲の中括弧は、別名_の可視性を制限するために使用される)

あなたは非常に頻繁にいくつかのフィールドを使用している場合は、直接それを別名設定できます:

auto &field = pointer->field;
// Even shorter alias:
auto &_ = pointer->busy_field;

まず、私は「で」誰が好きではないと聞きました。ルールは、C ++やJavaでクラスの内部で何が起こるかと何ら変わりは完全に簡単ではありません。そして、それは重要なコンパイラの最適化を引き起こすことができることを見落とさないようにしてくださいます。

数多くのパーサーを書かれた、これは、静的または動的名前付きオブジェクトのために死んで単純なリストのルックアップ、のように思えます。さらに、私は、コンパイラが正しく欠落しているオブジェクトとタイプなので、WITHを許可していないため、これらすべてのラメ言い訳を特定していなかった状況を見たことがない... ENDWITH工事はhooeyがたくさんあるように見えるでしょう。長いオブジェクト名になりやすい私たちの残りの部分については1つの回避策は、単純な定義を作成することです。私が持っているとし、抵抗することができませんでします:

    #include<something> 
    typedef int headache;
    class grits{
      public:
       void corn(void);
       void cattle(void);
       void hay(void);}; //insert function defs here
     void grits::grits(void)(printf("Welcome to Farm-o-mania 2012\n");};

    #define m mylittlepiggy_from_under_the_backporch.
    headache main(){
       grits mylittlepiggy_from_under_the_backporch;
         m corn();  //works in GCC
         m cattle();
         m hay();
      return headache;

以下のようなアプローチの意義に依存します。がコンパイラを支C++0xの auto を利用することができることなくブーストに依存する。

免責事項:ないでくださいこ任意のコードが必要であると考えている読みによって誰でも自分で数ヶ月):

#define WITH(src_var)                                             \
    if(int cnt_ = 1)                                              \
        for(BOOST_AUTO(const & _, src_var); cnt_; --cnt_)


int main()
{
    std::string str = "foo";

    // Multiple statement block
    WITH(str)
    {
        int i = _.length();
        std::cout << i << "\n";
    }

    // Single statement block
    WITH(str)
        std::cout << _ << "\n";

    // Nesting
    WITH(str)
    {
        std::string another("bar");
        WITH(another)
            assert(_ == "bar");
    }
}

私は1つのインスタンスを見ることができ、実際に便利です。

「を持ちます」

再帰的なデータ構造のための方法では、あなたはよくあるケースがあります:

void A::method()
{
  for (A* node = this; node; node = node->next) {
    abc(node->value1);
    def(value2); // -- oops should have been node->value2
    xyz(node->value3);
  }
}
このようなタイプミスによって引き起こさ

のエラーを見つけることは非常に困難です。

あなたが書くことができる 'で'

void A::method()
{
  for (A* node = this; node; node = node->next) with (node) {
    abc(value1);
    def(value2);
    xyz(value3);
  }
}

これはおそらく「は」の言及、他の全てのネガをoutweightしませんが、ちょうど興味深い情報など...

たぶん、あなたはできます:

auto p = *pointer;
if (p.field1) && (p.field2) && ... (p.fieldn)

またはC ++でwith文を理解し、有効なC ++のいくつかのフォームにそれらを翻訳します小さなプログラムを作成します。

いいえ、C / C ++にはwithキーワードはありません。

しかし、あなたには、いくつかのプリプロセッサのコードでそれを追加することができます:

/* Copyright (C) 2018 Piotr Henryk Dabrowski, Creative Commons CC-BY 3.0 */

#define __M2(zero, a1, a2, macro, ...) macro

#define __with2(object, as) \
    for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)

#define __with1(object) __with2(object, it)

#define with(...) \
    __M2(0, ##__VA_ARGS__, __with2(__VA_ARGS__), __with1(__VA_ARGS__))

使用方法:

with (someVeryLongObjectNameOrGetterResultOrWhatever) {
    if (it)
        it->...
    ...
}

with (someVeryLongObjectNameOrGetterResultOrWhatever, myObject) {
    if (myObject)
        myObject->...
    ...
}

簡体unoverloaded定義(いずれかを選択):

無名の(Kotlinスタイルit):

#define with(object) \
    for (typeof(object) &it = (object), *__i = 0; __i < (void*)1; ++__i)

と命名ます:

#define with(object, as) \
    for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)

もちろんforループは常に単一パスのみを持っていると、コンパイラによって最適化されます。

#include <iostream>

using namespace std;

template <typename T>
struct with_iter {
  with_iter( T &val ) : p(&val) {}

  inline T* begin() { return p; }
  inline T* end() { return p+1; }

  T *p;
};

#define with( N, I ) for( auto &N : with_iter<decltype(I)>(I) )

int main() {

  with( out , cout ) {
    out << "Hello world!" << endl;
  }

  return 0;
}

NUFは言った...

次のようにこれを行うための簡単な方法がある。

class MyClass
{
    int& m_x;

    public MyClass(int& x)
    {
        m_x = x;
        m_x++;
    }

    ~MyClass()
    {
        m_x--;
    }
}
int main():
{
    x = 0;
    {
        MyClass(x)  // x == 1 whilst in this scope
    }
}

私は誰が掃除機に私を取る前に、すべての日が長く、ちょうどこのダウン廃車のpythonを書いてきました。大きなプログラムでは、これは何かのために信頼性の高いカウントを保持する方法の例です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top