代码之家  ›  专栏  ›  技术社区  ›  David Woo

catchstd::编译时的函数分配

  •  7
  • David Woo  · 技术社区  · 9 年前

    我只允许使用 std::函数 在我的代码库中,如果它不进行任何分配。

    为此,我可以编写类似以下函数的内容,并仅用于创建函数实例:

    template< typename Functor>
    std::function<Functor> makeFunction( Functor f)
    {
        return std::function<Functor>(std::allocator_arg, DummyAllocator(), f);
    }
    

    如果在运行时使用了DummyAllocator,它将断言或抛出。

    理想情况下,我希望在编译时捕捉分配用例。

    template< typename Functor>
    std::function<Functor> makeFunction( Functor f)
    {
       static_assert( size needed for function to wrap f < space available in function, 
       "error - function will need to allocate memory");
    
       return std::function<Functor>(f);
     }
    

    这样的事情有可能吗?

    3 回复  |  直到 9 年前
        1
  •  2
  •   Niall    9 年前

    你的工厂方法可能是最好的选择。

    如果不合适,您可以选择为 function ; 使用 std::function 作为成员变量,以便适配器强制执行约束。

    template <typename S>
    class my_function {
      std::function<S> func_;
    public:
      template <typename F>
      my_function(F&& f) :
      func_(std::allocator_arg, DummyAllocator(), std::forward<F>(f))
      {}
      // remaining functions required include operator()(...)
    };
    
        2
  •  2
  •   user1095108    9 年前

    我会写一篇 std::function 未分配的替换,如 std::函数 如果需要分配内存,这里有一个 candidate .

        3
  •  0
  •   Potatoswatter    9 年前

    鉴于 std::function 库中的分配器支持,只需提供 std::函数 使用一个不工作的分配器。

    template< typename t >
    struct non_allocator : std::allocator< t > {
        t * allocate( std::size_t n ) { throw std::bad_alloc{}; }
        void deallocate( t * ) {}
    
        non_allocator() = default;
        template< typename u >
        non_allocator( non_allocator< u > const & ) {}
    
        template< typename u >
        struct rebind { typedef non_allocator< u > other; };
    };
    
    template< typename t, typename u >
    bool operator == ( non_allocator< t > const &, non_allocator< t > const & )
        { return true; }
    
    template< typename t, typename u >
    bool operator != ( non_allocator< t > const &, non_allocator< t > const & )
        { return false; }
    

    不幸的是,这在GCC中不起作用,因为它甚至没有声明任何 allocator_arg 的构造函数 function 。即使在Clang中,编译时错误也是不可能的,因为它不幸地使用了运行时 if 以决定是否使用分配器。