<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[beliebige anzahl argumente weiterleiten mit type erasure]]></title><description><![CDATA[<p>hi,</p>
<p>folgender code:</p>
<pre><code>#include &lt;utility&gt;
#include &lt;cmath&gt;
#include &lt;memory&gt;
#include &lt;type_traits&gt;
#include &lt;functional&gt;
#include &lt;map&gt;
#include &lt;initializer_list&gt;
#include &lt;iostream&gt;

using arg_t = double;

struct callable_t
{
	virtual ~callable_t() = default;
	virtual arg_t invoke( arg_t const* args ) const = 0;
};
template&lt; typename T &gt;
class one_arg_t : public callable_t
{
	T m_obj;

public:
	template&lt; typename... args_t &gt;
	one_arg_t( args_t&amp;&amp;... args )
		: m_obj( std::forward&lt; args_t &gt;( args )... )
	{
	}

	virtual arg_t invoke( arg_t const* args ) const override
	{
		return m_obj( args[0] );
	}
};
template&lt; typename T &gt;
auto make_one_arg( T&amp;&amp; obj )
{
	return std::move( std::make_unique&lt; one_arg_t&lt; std::decay_t&lt; T &gt; &gt; &gt;( std::forward&lt; T &gt;( obj ) ) );
}
template&lt; typename T &gt;
class two_args_t : public callable_t
{
	T m_obj;

public:
	template&lt; typename... args_t &gt;
	two_args_t( args_t&amp;&amp;... args )
		: m_obj( std::forward&lt; args_t &gt;( args )... )
	{
	}

	virtual arg_t invoke( arg_t const* args ) const override
	{
		return m_obj( args[0], args[1] );
	}
};
template&lt; typename T &gt;
auto make_two_args( T&amp;&amp; obj )
{
	return std::move( std::make_unique&lt; two_args_t&lt; std::decay_t&lt; T &gt; &gt; &gt;( std::forward&lt; T &gt;( obj ) ) );
}

class callables_t
{
	std::map&lt; std::size_t, std::unique_ptr&lt; callable_t &gt; &gt; m_callables;

public:
	template&lt; typename T, typename U &gt;
	void insert( T&amp;&amp; k, U&amp;&amp; v )
	{
		m_callables.insert( decltype( m_callables )::value_type{ std::forward&lt; T &gt;( k ), std::forward&lt; U &gt;( v ) } );
	}

	arg_t invoke( std::size_t n, arg_t const* args ) const
	{
		const auto finding = m_callables.find( n );
		if( finding == m_callables.end() )
		{
			throw std::logic_error{ &quot;invalid number of arguments&quot; };
		}
		return finding-&gt;second-&gt;invoke( args );
	}
};

int main()
{
	callables_t callables;
	callables.insert( 1, make_one_arg( static_cast&lt; arg_t( * )( arg_t )&gt;( &amp;std::sin ) ) );
	callables.insert( 2, make_two_args( static_cast&lt; arg_t( * )( arg_t, arg_t )&gt;( &amp;std::atan2 ) ) );
	const std::array&lt; arg_t, 2 &gt; args{ 3.14159265 / 2, args[ 0 ] };
	std::cout &lt;&lt; callables.invoke( 1, args.data() ) &lt;&lt; '\n';
	std::cout &lt;&lt; callables.invoke( 2, args.data() ) &lt;&lt; '\n';
}
</code></pre>
<p>ich benutze hier <code>one_arg_t</code> und <code>two_args_t</code> um einen pointer auf argumente 'zu entpacken'. faellt euch eine moeglichkeit ein, wie ich das so abaendern kann, dass ich nur noch die anzahl an parametern als template-argument uebergeben kann, so dass danach der pointer automatisch 'extrahiert' wird, wie oben zu sehen in z.b. zeile 53?</p>
<p>danke im voraus, lg</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/340038/beliebige-anzahl-argumente-weiterleiten-mit-type-erasure</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 12:30:40 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/340038.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 15 Oct 2016 13:38:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to beliebige anzahl argumente weiterleiten mit type erasure on Sat, 15 Oct 2016 13:38:43 GMT]]></title><description><![CDATA[<p>hi,</p>
<p>folgender code:</p>
<pre><code>#include &lt;utility&gt;
#include &lt;cmath&gt;
#include &lt;memory&gt;
#include &lt;type_traits&gt;
#include &lt;functional&gt;
#include &lt;map&gt;
#include &lt;initializer_list&gt;
#include &lt;iostream&gt;

using arg_t = double;

struct callable_t
{
	virtual ~callable_t() = default;
	virtual arg_t invoke( arg_t const* args ) const = 0;
};
template&lt; typename T &gt;
class one_arg_t : public callable_t
{
	T m_obj;

public:
	template&lt; typename... args_t &gt;
	one_arg_t( args_t&amp;&amp;... args )
		: m_obj( std::forward&lt; args_t &gt;( args )... )
	{
	}

	virtual arg_t invoke( arg_t const* args ) const override
	{
		return m_obj( args[0] );
	}
};
template&lt; typename T &gt;
auto make_one_arg( T&amp;&amp; obj )
{
	return std::move( std::make_unique&lt; one_arg_t&lt; std::decay_t&lt; T &gt; &gt; &gt;( std::forward&lt; T &gt;( obj ) ) );
}
template&lt; typename T &gt;
class two_args_t : public callable_t
{
	T m_obj;

public:
	template&lt; typename... args_t &gt;
	two_args_t( args_t&amp;&amp;... args )
		: m_obj( std::forward&lt; args_t &gt;( args )... )
	{
	}

	virtual arg_t invoke( arg_t const* args ) const override
	{
		return m_obj( args[0], args[1] );
	}
};
template&lt; typename T &gt;
auto make_two_args( T&amp;&amp; obj )
{
	return std::move( std::make_unique&lt; two_args_t&lt; std::decay_t&lt; T &gt; &gt; &gt;( std::forward&lt; T &gt;( obj ) ) );
}

class callables_t
{
	std::map&lt; std::size_t, std::unique_ptr&lt; callable_t &gt; &gt; m_callables;

public:
	template&lt; typename T, typename U &gt;
	void insert( T&amp;&amp; k, U&amp;&amp; v )
	{
		m_callables.insert( decltype( m_callables )::value_type{ std::forward&lt; T &gt;( k ), std::forward&lt; U &gt;( v ) } );
	}

	arg_t invoke( std::size_t n, arg_t const* args ) const
	{
		const auto finding = m_callables.find( n );
		if( finding == m_callables.end() )
		{
			throw std::logic_error{ &quot;invalid number of arguments&quot; };
		}
		return finding-&gt;second-&gt;invoke( args );
	}
};

int main()
{
	callables_t callables;
	callables.insert( 1, make_one_arg( static_cast&lt; arg_t( * )( arg_t )&gt;( &amp;std::sin ) ) );
	callables.insert( 2, make_two_args( static_cast&lt; arg_t( * )( arg_t, arg_t )&gt;( &amp;std::atan2 ) ) );
	const std::array&lt; arg_t, 2 &gt; args{ 3.14159265 / 2, args[ 0 ] };
	std::cout &lt;&lt; callables.invoke( 1, args.data() ) &lt;&lt; '\n';
	std::cout &lt;&lt; callables.invoke( 2, args.data() ) &lt;&lt; '\n';
}
</code></pre>
<p>ich benutze hier <code>one_arg_t</code> und <code>two_args_t</code> um einen pointer auf argumente 'zu entpacken'. faellt euch eine moeglichkeit ein, wie ich das so abaendern kann, dass ich nur noch die anzahl an parametern als template-argument uebergeben kann, so dass danach der pointer automatisch 'extrahiert' wird, wie oben zu sehen in z.b. zeile 53?</p>
<p>danke im voraus, lg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511660</guid><dc:creator><![CDATA[ulrich_mvp]]></dc:creator><pubDate>Sat, 15 Oct 2016 13:38:43 GMT</pubDate></item></channel></rss>