问题
I have this code:
...
#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) { ...
But when I try to compile it I receive this error:
error C2678: binary '==': no operator found which takes a left-hand operand of type 'const noRef' (or there is no acceptable conversion)
Why this happens, since noRef
is an alias for boost::tuple
and tuple_comparison
should manage this case?
ERROR FOUND, DON'T KNOW HOW TO SOLVE IT:
It seems that the error was in the std::tie
operation. So rewriting it as:
auto key = noRef{ boost::make_tuple(args ...) };
Works fine. The problem is that this solution is inefficient, since key
is a potentially expensive copy of the whole tuple, while using tie
is a tuple of references (much smaller). So, how can I take a reference to it->first
tuple? Should I use the same tie
trick?
回答1:
The only reason this line compiles at all is MSVC's Evil ExtensionTM which allows non-const lvalue references to bind to temporaries:
auto key = std::tie(noRef{ boost::make_tuple(args ...) });
This should simply be
auto key = boost::tie(args...);
which creates a boost::tuple
of references to be used for lookup later.
Also, as noted in the comments, the if
check should verify it != cache.end()
first before attempting to dereference it (thanks!).
Finally, const Args && ...
doesn't make much sense, as one is unlikely to want to accept const rvalues. It probably should be either const Args&...
or Args&&...
.
来源:https://stackoverflow.com/questions/36997854/no-defined-for-boosttuples