1

我有这个代码:

...
#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技巧吗?

4

1 回答 1

2

此行完全编译的唯一原因是 MSVC 的 Evil Extension TM允许非常量左值引用绑定到临时对象:

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

这应该只是

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

它创建了一个boost::tuple用于稍后查找的引用。

此外,如评论中所述,if检查应it != cache.end()在尝试取消引用之前先进行验证(谢谢!)。

最后,const Args && ...没有多大意义,因为人们不太可能想要接受 const 右值。它可能应该是const Args&...Args&&...

于 2016-05-03T10:17:44.840 回答