std::async
+std::launch::deferred
で一回だけ呼び出し可能な関数オブジェクト(のようなモノ)。
#include <future> #include <functional> // bad_function_call #include <utility> template <class R> class once_function { std::future<R> ftr_; public: template <class F, class... Args> explicit once_function(F&& f, Args&&... args) { ftr_ = std::async(std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...); } R operator()() { if (!ftr_.valid()) throw std::bad_function_call(); return ftr_.get(); } };
int f(std::unique_ptr<int> p) { return *p; } int main() { std::unique_ptr<int> up( new int(42) ); once_function<int> of(f, std::move(up)); int v0 = of(); // v0 == 42 int v1 = of(); // throw bad_function_call }