5

C++ で、その場でインターフェイスの実装を作成できますか (ローカル スコープ変数をバインドするのが理想的です)。それをより適切に説明する方法がわからないので、コードを次のように (大まかに) 表示したいと思います。

// Given the following:

class Visitor
{
    virtual void visit(const Data& data) = 0;
}

class DataStore
{
    void visitData(Visitor& visitor) { /** Invokes visitor with each item of data. */ }
}

// Imagine one would write something like:

void inSomeFunction(DataStore& store)
{
    std::string myName = "bob";

    class MyVisitor: public Visitor
    {
    public:
        MyVisitor(const std::string& p): person(p);
        virtual void visit(const Data& data) override
        {
            std::cout << person << " is visiting " << data << std::endl;
        }
    private:
        std::string person;
    }

    MyVisitor myVisitor(myName);
    store.visitData(myVisitor);
}

// Instead of the above, I want to write instead something like:

void inSomeFunction(DataStore& store)
{
    std::string myName = "bob";

    store.visitData(
        class: public MyVisitor
        {
            virtual void visit(const Data& data) override
            {
                std::cout << myName << " is visiting " << data << std::endl;
            }
        }
    );
}

ここで 2 つの質問をしていることに気付きました。このような匿名クラスを作成できますか。また、ローカル スコープから変数をバインドできますか (myName を参照したように)。しかし、それが役立つためには両方が必要です。

上記ができない場合、簡潔さ/ボイラープレートの欠如の観点から、たとえばC++ 11ラムダなどを使用することに最も近いものは何ですか。

4

2 に答える 2

10

インターフェイスが必要な場合は、Kerrek が提案したことを行う必要があります

ただし、インターフェースを次のように変更することをお勧めします。

class DataStore
{
    void visitData(Visitor& visitor) { 
        // bunch of calls to visitor.visit(...) ... 
    }
}

に:

    template <class Visitor>
    void visitData(Visitor visitor) { 
        // bunch of calls to visitor(...) ... 
    }

これにより、次のように簡単に書くことができます。

std::string myName = "bob";
store.visit([myName](const Data& data) {
    std::cout << myName << " is visiting " << data << std::endl;
});

私の意見では、これははるかに自然です。のインターフェイスがDataStore制御できない場合、この答えはまったく意味がありません。

于 2016-05-24T17:10:02.667 に答える