2

Visual Studio2008SP1で正常にコンパイルおよび実行される次のコードがあります。

#include <functional>
#include <iostream>

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>

class NoncopyableObject : public boost::noncopyable
{
public:
    NoncopyableObject(int x) : x_(x) {}
    int getValue() const {return x_;}
private:
    int x_;
};

template<class F>
class MenuItemDispatcher
{
public:
    MenuItemDispatcher(F f) : f_(f) { }

    void operator ()(NoncopyableObject& w) const
    {
        // Invoke the functor
        f_(w);
    }
private:
    typedef boost::function1<void,NoncopyableObject&> FUNC;
    FUNC f_;
};

void MenuItem()
{
    std::cout << "in MenuItem()\n";
}

template<class F>
MenuItemDispatcher<F> MakeMenuItemDispatcher(F f)
{
    return MenuItemDispatcher<F>(f);
}

int main()
{
    NoncopyableObject obj(7);
    MakeMenuItemDispatcher(boost::bind(&MenuItem))(obj);
}

main()でboost::bindをstd::tr1 :: bindに変更すると、エラーが発生します。

エラーC2248::'boost::noncopyable_::noncopyable::noncopyable'クラスで宣言されたプライベートメンバーにアクセスできません'boost::noncopyable_::noncopyable'

この診断は、コンパイラによって生成された関数で発生しました'NoncopyableObject::NoncopyableObject(const NoncopyableObject &)'

したがって、NoncopyableObjectのコピーコンストラクターを生成しようとしています。なぜこれがそうなるのか誰もが知っていますか?MenuItemDispatcherの呼び出し演算子はNoncopyableObjectへの参照を取得するため、何が問題になっているのかを確認するのに苦労しています。

4

1 に答える 1

4

bindこれは、MS Visual Studio(2010を含む)とGNU gcc(4.4.1と4.5.2をテストしましたが、どちらも期待どおりに機能します)での実装方法に違いがあるようです。

あなたの定義を踏まえて、次のコードを検討してください

auto b = boost::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj);  // OK in VS and GCC

boost::bindをstd::bindに置き換えます(私は2010を使用していますが、エラーメッセージは2008年と同じように見えます)

auto b = std::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj);  // compile error in VS 2010 SP1, OK in GCC
b(std::reference_wrapper<NoncopyableObject>(obj)); // OK in both

したがって、MSはbind()、引数が使用されない場合でもその引数のコピーを作成しますが、boostとGCCbind()はその引数をまったく気にしません。

FUNCtypedefを次のように変更することで、(2010年に)コンパイルして実行する例を取得できました。

typedef boost::function1<void, std::tr1::reference_wrapper<NoncopyableObject> > FUNC;
于 2011-07-11T19:06:55.713 に答える