?
hi,
folgender code:
#include <utility>
#include <cmath>
#include <memory>
#include <type_traits>
#include <functional>
#include <map>
#include <initializer_list>
#include <iostream>
using arg_t = double;
struct callable_t
{
virtual ~callable_t() = default;
virtual arg_t invoke( arg_t const* args ) const = 0;
};
template< typename T >
class one_arg_t : public callable_t
{
T m_obj;
public:
template< typename... args_t >
one_arg_t( args_t&&... args )
: m_obj( std::forward< args_t >( args )... )
{
}
virtual arg_t invoke( arg_t const* args ) const override
{
return m_obj( args[0] );
}
};
template< typename T >
auto make_one_arg( T&& obj )
{
return std::move( std::make_unique< one_arg_t< std::decay_t< T > > >( std::forward< T >( obj ) ) );
}
template< typename T >
class two_args_t : public callable_t
{
T m_obj;
public:
template< typename... args_t >
two_args_t( args_t&&... args )
: m_obj( std::forward< args_t >( args )... )
{
}
virtual arg_t invoke( arg_t const* args ) const override
{
return m_obj( args[0], args[1] );
}
};
template< typename T >
auto make_two_args( T&& obj )
{
return std::move( std::make_unique< two_args_t< std::decay_t< T > > >( std::forward< T >( obj ) ) );
}
class callables_t
{
std::map< std::size_t, std::unique_ptr< callable_t > > m_callables;
public:
template< typename T, typename U >
void insert( T&& k, U&& v )
{
m_callables.insert( decltype( m_callables )::value_type{ std::forward< T >( k ), std::forward< U >( 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{ "invalid number of arguments" };
}
return finding->second->invoke( args );
}
};
int main()
{
callables_t callables;
callables.insert( 1, make_one_arg( static_cast< arg_t( * )( arg_t )>( &std::sin ) ) );
callables.insert( 2, make_two_args( static_cast< arg_t( * )( arg_t, arg_t )>( &std::atan2 ) ) );
const std::array< arg_t, 2 > args{ 3.14159265 / 2, args[ 0 ] };
std::cout << callables.invoke( 1, args.data() ) << '\n';
std::cout << callables.invoke( 2, args.data() ) << '\n';
}
ich benutze hier one_arg_t und two_args_t 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?
danke im voraus, lg