嵌套 boost::lambda::bind-s 问题

发布于 2024-07-17 09:43:46 字数 1636 浏览 8 评论 0原文

我有一个通用函数:

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) : error C2665: 'boost::lambda::function_adaptor::apply' :没有 2 个元素重载可以转换所有参数类型”。

我在这里做错了什么?

顺便提一句

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

I have a generic function:

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

    ...
}

I can successfully call:

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

Then, instead of adding a quantity of a certain format to a thumbnail, I need to replace them all with a single format. More precise, with a list of 1 element, like that:

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

Which results in "boost/lambda/detail/actions.hpp(96) : error C2665: 'boost::lambda::function_adaptor::apply' : none of the 2 overloads could convert all the argument types".

What am I doing wrong here?

BTW

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝不服输 2024-07-24 09:43:46

您是否在使用 lambda 的代码中碰巧 #include boost/bind.hpp ? 这将导致不合格地使用占位符(_1、_2 等)来解析 Boost.Bind 定义的占位符,并且这些占位符不能与 Boost.Lambda 很好地混合。

重写代码以显式使用 boost::lambda::_[1,2,3] 而不是不合格的名称,可以在我的 VC 7.1 设置上正常编译。

Do you happen to #include boost/bind.hpp in your lambda-using code? This would cause unqualified use of the placeholders (_1, _2, etc) to resolve to those defined by Boost.Bind, and these don't mix well with Boost.Lambda.

Rewriting your code to explicitly use boost::lambda::_[1,2,3] instead of the unqualified names compiles fine on my VC 7.1 setup.

も让我眼熟你 2024-07-24 09:43:46

不确定您使用的 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' :3 个重载中没有一个可以转换所有参数类型

错误。

当然,您可以只使用:

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

ExpressButtonPressed (func);

更清晰并且可以编译

Not sure what version of Boost or what compiler are you using. With boost 1.37 and VS2005 i can get the same error. I suspect it may be that an error at the heart of the template expansion is causing a SFINAE issue.

For instance taking the innermost expression out:

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

That looks ok to me yet also fails, albeit with a :

std::pair<_Ty1,_Ty2>::pair' : none of the 3 overloads could convert all the argument types

error.

Of course you could just use:

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

ExpressButtonPressed (func);

which is clearer and compiles.

策马西风 2024-07-24 09:43:46

我认为在第一次绑定时,您应该将构造对象(由第二次绑定产生)绑定为方法的第一个参数(它应该是构造对象的地址):

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

我没有尝试编译代码。 另一个可能的问题是第二个绑定函子可能按值返回构造的对象,而第一个绑定需要一个指向对象的指针(如 this 指针),因此您仍然需要一个指针作为 SetFormats 的第一个绑定参数。

I think at the first bind, you should bind the constructed object (resulted from the second bind) as first parameter of the method (it should be the address of the constructed object):

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

I didn't try to compile the code. One other possible issue is that the second bind functor might return the constructed object by value, and the first bind requires a pointer to object (as this pointer), so you still need a pointer as first bound parameter for SetFormats.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文