2016-05-03 4 views
1

J'ai ce code:pas == défini pour boost :: tuples

... 
#include "boost/tuple/tuple_comparison.hpp" 
... 
template <typename ReturnType, typename... Args> 
function<ReturnType(Args...)> memoize(const Args && ... args) 
{ 
    using noRef = boost::tuple<typename std::remove_reference<Args>::type...>; 
    static map<noRef, ReturnType, less<>> cache; 
    auto key = std::tie(noRef{ boost::make_tuple(args ...) }); 
    auto it = cache.lower_bound(key); 
    ReturnType result; 
    if (it->first == key) { ... 

Mais lorsque je tente de compiler je reçois cette erreur:

error C2678: binary '==': no operator found which takes a left-hand operand of type 'const noRef' (or there is no acceptable conversion) 

Pourquoi cela se produit, puisque noRef est un alias pour boost::tuple et tuple_comparison devrait gérer ce cas?

ERREUR TROUVE, NE SAVENT PAS RÉSOLVIONS:

Il semble que l'erreur était dans l'opération std::tie. Donc réécrire comme:

auto key = noRef{ boost::make_tuple(args ...) }; 

Fonctionne bien. Le problème est que cette solution est inefficace, puisque key est une copie potentiellement coûteuse de l'entier, alors que tie est un tuple de références (beaucoup plus petit). Alors, comment puis-je prendre une référence à it->first tuple? Dois-je utiliser le même truc tie?

+0

Avec quels types instanciez-vous cela? 'operator ==' pour les tuples ne fonctionne que si tous les types d'éléments supportent 'operator =='. –

+0

Qu'est-ce que vous essayez de faire ici: 'std :: tie (noRef {boost :: make_tuple (args ...)});' '. Aussi, si vous pouvez utiliser 'std :: tie', alors pourquoi ne pas utiliser' std :: tuple'? – Nawaz

+1

En outre, que fait 'const' dans' const Args && '? – Nawaz

Répondre

2

La seule raison pour laquelle cette ligne compile tout est mal Extension de MSVC TM qui permet aux références lvalue non-const de se lier à des temporaires:

auto key = std::tie(noRef{ boost::make_tuple(args ...) }); 

Cela devrait simplement être

auto key = boost::tie(args...); 

qui crée un boost::tuple de références à utiliser pour la recherche ultérieure.

En outre, comme indiqué dans les commentaires, la vérification if doit d'abord vérifier it != cache.end() avant d'essayer de le déréférencer (merci!).

Enfin, const Args && ... n'a pas beaucoup de sens, car il est peu probable que l'on veuille accepter des valeurs constantes. Il devrait probablement être const Args&... ou Args&&....