Bonjour à toutes et à tous !

Je cherche à mémoizer une fonction F. J'ai piqué des bouts de code ici : http://cpptruths.blogspot.com/2012/0...moization.html
Toutefois, la différence est que dans mon cas, la fonction F renvoie un foncteur D très lourd (c'est une distribution avec un gros support, qui est longue à construire, et coûteuse à copier). Mon but est donc à la fois de construire D une seule fois, mais aussi d'éviter toutes les opérations de copies pour amener D là où on en a besoin.
J'ai donc modifié le code initial pour aboutir à la version suivante. Comme c'est un bout de code critique, j'aimerais m'assurer que je ne fais pas d'opérations inutiles. Sauf que je suis sûr que j'en ai fait tout plein ! Qu'en pensez-vous ?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
template<typename Ret, typename... Args>
auto memoize( Ret(*func)(Args...) ) {
  auto cache = std::make_shared<std::map<std::tuple<Args...>, Ret>>();
  return ([=](Args... args) mutable  {
        std::tuple<Args...> t(args...);
        if (cache->find(t) == cache->end())
            (*cache)[t] = std::move(func(args...));
        return std::cref((*cache)[t]);
        });
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
template <typename Sig, Sig funcptr>
struct static_memoizer;
 
template <typename F_ret, typename... F_args, F_ret (*func)(F_args...)>
struct static_memoizer<F_ret (*)(F_args...), func> {
  static auto get() {
    static auto mfunc (memoize(func));
    return mfunc;
  }
};
Et du coup je l'utilise comme ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
template<typename BigInt, typename BigFloat>
struct in_memoized_distribution{
  template<typename Generator>
  static std::vector<unsigned int> const& build(unsigned int k, unsigned int N, Generator& g){
    return utils::static_memoizer<
        decltype(&coalescence::make_occupancy_spectrum_distribution<BigInt, BigFloat>),
        &coalescence::make_occupancy_spectrum_distribution<BigInt, BigFloat>
      >::get()(k,N)(g);
  }
};
Merci d'avance