Повышение вложенности задач :: lambda :: bind-s - PullRequest
2 голосов
/ 17 апреля 2009

У меня есть общая функция:

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 элемента, например:

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): ошибка C2665:« boost :: lambda :: function_adaptor :: apply »: ни одна из двух перегрузок не может преобразовать все типы аргументов».

Что я здесь не так делаю?

КСТАТИ

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

Ответы [ 3 ]

4 голосов
/ 17 апреля 2009

Случайно ли вы #include boost / bind.hpp в вашем лямбда-коде? Это может привести к тому, что неквалифицированное использование заполнителей (_1, _2 и т. Д.) Будет преобразовано в определения, определенные Boost.Bind, и они плохо сочетаются с Boost.Lambda.

Переписывание кода для явного использования boost :: lambda :: _ [1,2,3] вместо неквалифицированных имен прекрасно компилируется в моей настройке VC 7.1.

0 голосов
/ 17 апреля 2009

Я думаю, что при первом связывании вы должны связать построенный объект (полученный в результате второго связывания) как первый параметр метода (это должен быть адрес построенного объекта):

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
    )
);

Я не пытался скомпилировать код. Еще одна возможная проблема заключается в том, что второй функтор связывания может возвращать построенный объект по значению, а для первого связывания требуется указатель на объект (как этот указатель), поэтому вам все еще нужен указатель в качестве первого связанного параметра для SetFormats.

0 голосов
/ 17 апреля 2009

Не уверен, какую версию Boost или какой компилятор вы используете. С 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 ': ни одна из трех перегрузок не может преобразовать все типы аргументов

ошибка.

Конечно, вы можете просто использовать:

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

ExpressButtonPressed (func);

, что яснее и компилируется .

...