2

私は一般的な機能を持っています:

void ImageAlbum::ExpressButtonPressed(
    boost::function<
        void (
            thumb::PhotoPrintThumbnail*,
            thumb::PhotoPrintFormat,
            thumb::PhotoPrintQuantity
        )
    > memberToCall
) {
    ...

    BOOST_FOREACH(thumb::PhotoPrintThumbnail *pThumbnail, m_thumbs.GetSelected()) {
    memberToCall(
            pThumbnail,
            m_expressSel.GetSelectedFormat(),
            m_expressSel.GetSelectedQuantity()
        );
    }

    ...
}

私は正常に呼び出すことができます:

ExpressButtonPressed(boost::bind(&thumb::PhotoPrintThumbnail::AddQuantity, _1, _2, _3));

次に、特定のフォーマットをサムネイルに追加するのではなく、それらすべてを 1 つのフォーマットに置き換える必要があります。より正確には、次のように 1 つの要素のリストを使用します。

ExpressButtonPressed(
    boost::lambda::bind(
        &thumb::PhotoPrintThumbnail::SetFormats,
        _1,
        boost::lambda::bind(
            boost::lambda::constructor<thumb::PhotoPrintThumbnail::LoadedFormats>(),
            1,
            boost::lambda::bind(
                boost::lambda::constructor<thumb::PhotoPrintThumbnail::LoadedFormat>(),
                _2,
                _3
            )
        )
    )
);

その結果、「boost/lambda/detail/actions.hpp(96): error C2665: 'boost::lambda::function_adaptor::apply': none of the 2 overloads could convert the all argument types".

ここで何が間違っていますか?

ところで

class PhotoPrintThumbnail {
public:
...
    typedef std::pair<PhotoPrintFormat, PhotoPrintQuantity> LoadedFormat;
    typedef std::list<LoadedFormat> LoadedFormats;
    void SetFormats(const LoadedFormats &formats);
4

3 に答える 3

4

ラムダを使用するコードに Boost/bind.hpp を #include することがありますか? これにより、プレースホルダー (_1、_2 など) の不適切な使用が Boost.Bind によって定義されたものに解決され、これらは Boost.Lambda とうまく混ざりません。

修飾されていない名前の代わりに boost::lambda::_[1,2,3] を明示的に使用するようにコードを書き直すと、VC 7.1 セットアップで正常にコンパイルされます。

于 2009-04-17T19:57:36.837 に答える
0

Boost のバージョンや使用しているコンパイラが不明です。ブースト 1.37 と VS2005 を使用すると、同じエラーが発生する可能性があります。テンプレート展開の中心にあるエラーが SFINAE の問題を引き起こしているのではないかと思います。

たとえば、最も内側の式を取り出します。

boost::function<
    PhotoPrintThumbnail::LoadedFormat (
            PhotoPrintFormat,
            PhotoPrintQuantity
    )
> func = boost::lambda::bind
                ( boost::lambda::constructor<PhotoPrintThumbnail::LoadedFormat>()
                , _1
                , _2
                );

それは私には問題ないように見えますが、失敗しますが、 :

std::pair<_Ty1,_Ty2>::pair' : 3 つのオーバーロードのいずれも、すべての引数の型を変換できませんでした

エラー。

もちろん、次のように使用できます。

void func
( PhotoPrintThumbnail* ppt
, const PhotoPrintFormat& ppf
, const PhotoPrintQuantity& ppq
)
{
    ppt->SetFormats (PhotoPrintThumbnail::LoadedFormats (1, PhotoPrintThumbnail::LoadedFormat (ppf, ppq)));
}

ExpressButtonPressed (func);

これはより明確でコンパイルされます

于 2009-04-17T12:52:21.243 に答える
0

最初のバインドでは、構築されたオブジェクト (2 番目のバインドの結果) をメソッドの最初のパラメーターとしてバインドする必要があると思います (構築されたオブジェクトのアドレスである必要があります)。

ExpressButtonPressed(
    boost::lambda::bind(
        &thumb::PhotoPrintThumbnail::SetFormats,
        boost::lambda::bind(
                boost::lambda::constructor<thumb::PhotoPrintThumbnail::LoadedFormats>(),
                1,
                boost::lambda::bind(
                        boost::lambda::constructor<thumb::PhotoPrintThumbnail::LoadedFormat>(),
                        _2,
                        _3
                )
        ),
        _1
    )
);

コードをコンパイルしようとしませんでした。もう 1 つの考えられる問題は、2 番目のバインド ファンクターが構築されたオブジェクトを値で返す可能性があり、最初のバインドではオブジェクトへのポインター (このポインターとして) が必要であるため、SetFormats の最初のバインドされたパラメーターとしてポインターが引き続き必要になることです。

于 2009-04-17T12:58:49.527 に答える