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問題は、タプル全体の潜在的に高価なコピーであるのに対し、 usingtieは参照のタプル (はるかに小さい) であるため、このソリューションは非効率的であるということです。it->firstでは、どうすればタプルへの参照を取得できますか? 同じtieトリックを使用する必要がありますか?

4

1 に答える 1

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 右辺値を受け入れたくない可能性が高いため、あまり意味がありません。おそらく または のいずれかである必要がありconst Args&...ますArgs&&...

于 2016-05-03T10:17:44.840 に答える