我有这段代码:
...
#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) { ...
但是当我尝试编译它时,我收到了这个错误:
error C2678: binary '==': no operator found which takes a left-hand operand of type 'const noRef' (or there is no acceptable conversion)
为什么会发生这种情况,因为noRef
是boost::tuple
的别名而tuple_comparison
应管理此案例?
发现错误,不知道如何解决它:
似乎错误发生在std::tie
操作中。所以把它重写为:
auto key = noRef{ boost::make_tuple(args ...) };
工作正常。问题是这个解决方案是低效的,因为key
是整个元组的潜在昂贵副本,而使用tie
是一个引用元组(小得多)。那么,我如何参考it->first
元组?我应该使用相同的tie
技巧吗?
答案 0 :(得分:2)
此行编译的唯一原因是MSVC的Evil Extension TM ,它允许非const值左右引用绑定到临时值:
auto key = std::tie(noRef{ boost::make_tuple(args ...) });
这应该只是
auto key = boost::tie(args...);
创建boost::tuple
个引用,以便稍后查找。
此外,正如评论中所述,if
检查应首先验证it != cache.end()
,然后再尝试取消引用它(谢谢!)。
最后,const Args && ...
没有多大意义,因为人们不太可能想接受const rvalues。它可能应该是const Args&...
或Args&&...
。