tuple als Parameter für Funktionsobjekt



  • Hallöle,

    Ich habe ein std::tuple von Funktionsobjekten, nennen wir sie F..., sowie ein Funktionsobjekt G. G hat als Member ein Funktionsobjekt H und das std::tuple.

    Nun soll H mit den Rückgabewerten der Aufrufe der Funktionsobjekte F... mit den Parametern von G aufgerufen werden, oder in Code:

    template <typename H, typename... F>
    struct G
    {
        template <typename... Args>
        auto operator () (Args&&... args) -> ...
        {
            // rufe h mit den Ergebnissen von f(std::forward<Args>(args)...) für jedes F auf
        }
    
    private:
        H h;
        std::tuple<F...> f;
    };
    

    Geht das irgendwie?

    Grüße,
    PI



  • Da musst du das tuple wohl händisch unrollen.



  • D.h.? 😕



  • 314159265358979 schrieb:

    D.h.? 😕

    tuple<F...> == tuple<Head, Tail...>
    und so kannst du rekursiv dir immer den Head aus dem Tuple schnappen und die Funktion aufrufen.

    Die Rückgabewerte musst du halt speichern wenn du sie noch brauchst. Was erwartet H denn?



  • Mit H hab ich der Einfachheit ein bisschen gemogelt. H ist operator new für einen bestimmten Typ T, die Funktionsobjekte liefern die Argumente für new.



  • 314159265358979 schrieb:

    Mit H hab ich der Einfachheit ein bisschen gemogelt. H ist operator new für einen bestimmten Typ T, die Funktionsobjekte liefern die Argumente für new.

    Das erklärt nicht genau was du willst.
    Willst du h(...) für jedes Element in f einmal aufrufen oder einmal h mit einer Liste der rückgabewerte von allen Elementen in f?



  • Habs 😃

    Lösung:

    template <unsigned...>
    	struct indices {};
    
    	template <unsigned N, typename I>
    	struct append;
    
    	template <unsigned N, unsigned... I>
    	struct append<N, indices<I...>>
    	{
    		typedef indices<I..., N> type;
    	};
    
    	template <unsigned N>
    	struct make_indices_impl
    	{
    		typedef typename append<N, typename make_indices_impl<N - 1>::type>::type type;
    	};
    
    	template <>
    	struct make_indices_impl<0>
    	{
    		typedef indices<0> type;
    	};
    
    	template <unsigned N>
    	struct make_indices
    	{
    		typedef typename make_indices_impl<N - 1>::type type;
    	};
    
    	template <>
    	struct make_indices<0>
    	{
    		typedef indices<> type;
    	};
    
    	template <typename T, typename... Expr>
    	struct new_expression : expression<new_expression<T>>
    	{
    		new_expression(Expr... expr)
    			: expr{ expr... }
    		{}
    
    		template <typename... Args>
    		T* operator () (Args&&... args) const
    		{
    			return impl(typename make_indices<sizeof...(Expr)>::type(), std::forward<Args>(args)...);
    		}
    
    	private:
    		template <unsigned... N, typename... Args>
    		T* impl(indices<N...>, Args&&... args) const
    		{
    			return new T(std::get<N>(expr)(std::forward<Args>(args)...)...);
    		}
    
    		std::tuple<Expr...> const expr;
    	};
    


  • Irgendwie tut mir bei soetwas der Compiler immer leid. 😉


Anmelden zum Antworten