Question

J'ai une fonction générique:

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

    ...
}

Je peux appeler avec succès:

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

Ensuite, au lieu d'ajouter une quantité d'un certain format à une vignette, je dois les remplacer tous avec un format unique. Plus précisément, avec une liste de 1 élément, comme ça:

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

Ce qui se traduit par "boost / lambda / détail / actions.hpp (96): erreur C2665: 'boost :: lambda :: function_adaptor :: appliquer': aucun des 2 pourrait convertir tous surcharges les types d'arguments".

Qu'est-ce que je fais mal ici?

BTW

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

La solution

Avez-vous arriver à #inclure boost / bind.hpp dans votre code lambda utilisant? Cela provoquerait une utilisation sans réserve des espaces réservés (_1, _2, etc.) pour résoudre à ceux définis par Boost.Bind, et ceux-ci ne se mélangent pas bien avec Boost.Lambda.

Réécrire votre code pour utiliser explicitement boost :: lambda :: _ [1,2,3] au lieu des noms non qualifiés très bien sur mon compile configuration VC 7.1.

Autres conseils

Je ne sais pas quelle version de Boost ou quel compilateur utilisez-vous. Avec boost 1,37 et VS2005 je peux obtenir la même erreur. Je pense qu'il peut être qu'une erreur au cœur de l'expansion du modèle est à l'origine d'un problème SFINAE.

Par exemple en prenant l'expression la plus profonde sur:

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

Cela me semble ok encore échoue également, mais avec un:

std :: pair <_Ty1, _Ty2> :: paire »: aucun des 3 pourrait convertir tous surcharges les types d'arguments

erreur.

Bien sûr, vous pouvez simplement utiliser:

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

ExpressButtonPressed (func);

qui est plus clair et compiles .

Je pense que lors de la première liaison, il faut lier l'objet construit (traduite à partir de la deuxième liaison) en tant que premier paramètre de la méthode (il devrait être l'adresse de l'objet construit):

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

Je n'ai pas essayé de compiler le code. Un autre problème possible est que le second foncteur de liaison peut renvoyer l'objet construit par la valeur, et la première liaison nécessite un pointeur vers l'objet (comme ce pointeur), de sorte que vous avez encore besoin d'un pointeur comme premier paramètre lié pour SetFormats.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top