2009-04-17 62 views
2

我有一个通用的功能:问题嵌套的boost ::拉姆达::绑定-S

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

这导致“升压/λ/细节/ actions.hpp(96):错误C2665:“提高::拉姆达:: function_adaptor ::应用':2个重载都不能转换所有的参数类型“。

我在这里做错了什么?

BTW

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

我不寒而栗,认为我可能不得不保持你的代码有一天..;) – 2009-04-17 09:41:55

回答

4

你碰巧在使用lambda的代码中#include boost/bind.hpp?这会导致占位符(_1,_2等)的不合格使用来解决由Boost.Bind定义的占位符,并且这些不能与Boost.Lambda混合使用。

重写你的代码以显式使用boost :: lambda :: _ [1,2,3]而不是非限定名称在我的VC 7.1设置上编译得很好。

0

不知道你使用的是什么升压或什么编译器的版本。随着升压1.37和VS2005我可以得到相同的错误。我怀疑这可能是模板扩展的核心错误导致了SFINAE问题。

例如采取最里面表达出来:

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

这看起来确定,但我也失败了,尽管有:

的std ::对< _Ty1,_Ty2> ::对”: 3重载中没有一个可以转换所有参数类型

错误。

当然,你可以只使用:

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

ExpressButtonPressed (func); 

这是更清晰并编译

0

我认为在第一绑定,则应该将构造的对象(产生于第二结合)作为该方法的第一个参数结合(它应该是所构造的对象的地址):

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的第一个绑定参数。