I would like to create a simple factory method with a simple C++ syntax:
void *createObject(const char *str,...)
{
if(!strcmp("X",str))
return new X(...);
}
I cannot figure out the syntax for this. I've been looking at template metaprogramming and use mpl::vectors, but I am not sure how to pass down this syntax. I want to really avoid using C va_lists if possible and go for a clean syntax like the one above.
This would be a better approach on C++11:
template< typename ...Args >
std::shared_ptr<void> createObject( std::string const& name, Args&& ...args )
{
if( name == "X" )
{
return try_make_shared< X >( std::forward< Args >( args )... );
}
/* other cases here*/
return nullptr;
}
template< typename T, typename ...Args >
typename std::enable_if<
std::is_constructible< T, Args >::value
, std::shared_ptr< T >
>::type try_make_shared( Args&&... args )
{
return std::make_shared< X >( std::forward< Args >( args )... );
}
template< typename T, typename ...Args >
typename std::enable_if<
!std::is_constructible< T, Args >::value
, std::shared_ptr< T >
>::type try_make_shared( Args&&... args )
{
throw std::invalid_argument( "The type is not constructible from the supplied arguments" );
return nullptr;
}
The differences with your code are
It uses a variadic template function instead of an ellipsis argument, thus the number and type of the parameters are still available at compile time (you don't loose type checking). Additionally you can call this function with non-POD types.
It returns a shared_ptr<void> instead of a plain void*. This allows you to control from within the factory how the object should be cleaned once all references to it are gone. The user doesn't need to know or care if he should call the standard delete, or maybe a deleteObject method from your factory.
Update: For those suggesting unique_ptr, you can read here about the possibilities that a shared_ptr brings to the table. A restricted factory that does only ever return pointers to new-ly allocated objects may and should use a unique_ptr.
In addition to the code on how to create objects using the nice C++11 variadic templates (as seen in K-ballo's answer), this answer shows how I would handle a set of classes in a project. This method is a big hack and only recommended if you know what you're doing, however, when adding new classes to your project, you only have to add them to a single file listing all your classes, so if the project gets huge, it helps to keep the overview.
Use this approach only, if you have to list your classes multiple times, for example if you also want to have a std::string className() function, for example, returning the name of a class without using C++ runtime type information. Every such function which requires to list all classes in your project can be implemented in a similar way than the following.
classes.h
/* For every class in your project which should be creatable through your
* factory, add a line here. */
CLASS(Foo)
CLASS(Bar)
CLASS(Baz)
factory.cpp
template< typename ...Args >
std::shared_ptr<void> createObject( std::string const& name, Args&& ...args )
{
// Define what code to insert for every class:
#define CLASS(T) \
else if(name == #T) \
return std::make_shared<T>(std::forward(args)...);
// List all cases:
if(0) /*do nothing*/; // <-- needed because the macro uses else if
#include "classes.h"
#undef CLASS
return nullptr;
}
If you can't use variadic templates, and don't want to use C-style varargs, your only option is to come up with some common representation for the arguments.
boost::shared_ptr<void> createObject(const char *str,
int argc, const char *argv[])
{
if(!strcmp("X",str))
return new X(argc, argv);
if(!strcmp("Y",str))
return make_Y(argc, argv);
}
as illustrated for Y, it may be sensible to split the argument handling out into a factory function instead of coupling your constructor to the option format. For example, you might want to switch to a property map or Boost program options.
The solution I ended up using was to create 0, N singletons with templated parameters. It is working pretty well with N = 8. A bit ugly, but only needs to be done once.
Related
The sd-bus requires one to callback functions when defining d-bus methods. As i am doing C++14, i would like to have those calls to a class object on_msg_method_here() functions. What i am trying to achieve is something like this (in pseudo c++):
int callback_dbus_method_foo( message* msg, void* userdata, ... )
{
MyClass* cls = (MyClass*)userdata;
Type0 var0;
if ( message_process( msg, signature[0], &var0 ) != 0 )
//.. error here
Type1 var1;
if ( message_process( msg, signature[1], &var1 ) != 0 )
//.. error here
//... and these continue from 0 to N
TypeN varN;
if ( message_process( msg, signature[N], &varN ) != 0 )
//.. error here
int dbus_ret = cls->on_msg_method_foo( var1, var2, ..., varN )
handle_dbus_ret( msg, dbus_ret // ... );
return 0;
}
int MyClass::register_callbacks( ... )
{
// Well really we have something really different, this is to demonstrate
// pass 'this' as userdata* to callback function
dbus_register_callback( "method_foo",
&callback_dbus_method_foo, this )
}
Now i know i can do this with C-macros, but how to do this properly with C++14 varidic macros?
As far as i understand, the trouble of calling certain class object certain method can be handled with std::bind (and pass that via userdata pointer), and the variable declaration and message_process can be done with variadic template peeling, but how to get those declared variables (var0, var1, .. on the pseudo code example) expanded properly to the call? In short, how to do this magic:
MyClass::register_callbacks()
{
Mystic fun_to_call = std::bind( &MyClass::on_dbus_method_foo, this );
dbus_register_callback( "method_foo",
super_magic_template<int,double,bool>, &fun_to_call );
}
There are a couple things I would do in order to get an elegant and generic solution.
We need a way to gather variables (var0, var1, ..., varN) and pass them to a function. For that, I would first have a wrapper that queries such variables given it's index i. I'm not sure what signature is in your exemple, but I'm sure you can work around this.
template <class T>
T get_var(message* msg, unsigned i) {
T var;
if ( message_process( msg, signature[i], &var ) != 0)
throw std::runtime_error("Oups"); // In this context, it's easier to deal with errors with exception.
return var;
}
We can then gather all variables by unpacking variadic template arguments, along with associated index_sequence used for indexing. Something like
template <class... Vars, class F>
void callback_wrapper(F& fcn, message* msg) {
callback_wrapper_impl(fcn, msg, std::make_index_sequence<sizeof...(Vars)>());
}
template <class... Vars, class F, size_t... i>
void callback_wrapper_impl(F& fcn, message* msg, std::index_sequence<i...>) {
fcn(get_var<Vars>(msg, i)...);
}
Another difficulty arises with using std::bind, which returns the function-like object fun_to_call. We can't pass that to dbus_register_callback as a function pointer, which does not carry any data, neither can we pass a pointer to it as userdata, because fun_to_call is a local variable, hence it's lifetime is too short.
Instead of relying only on a super_magic_template callback, I would do a wrapper around dbus_register_callback that offers a simpler interface, let's call it modern_dbus_register_callback. The most straightforward solution I see is to use dynamic storage duration at the cost of memory allocation and an extra level of indirection - this is similar to type erasure used in std::function. Note that you can optimize this if sizeof(fun_to_call) < sizeof(void*), by passing fun_to_call by value as userdata - this is small value optimization. I believe using lambdas with no capture can be useful, as they are convertibles to function pointers and avoid lots of template boilerplate. Some extra work might be required to handle errors while avoiding memory leaks.
template <class... Vars, class F>
void modern_dbus_register_callback(const char* name, F& fcn) {
std::unique_ptr<F> fcn_ptr = std::make_unique<F>(fcn);
dbus_register_callback(name, [](message* msg, void* userdata){
std::unique_ptr<F> fcn_ptr(static_cast<F*>(userdata));
callback_wrapper<Vars...>(*fcn_ptr, msg);
}, fcn_ptr.release());
}
This can then be used as
modern_dbus_register_callback<int,double,bool>("method_foo", fun_to_call);
I have to wrap a getter function into a std::future object.
std::function<String (String)> -> std::function<std::future<String> (String)>
So simple question, what is the best / fastest way to do this?
Here are two options I came up with.
I have a function:
std::function<String (String)> getter;
Then wrap this using std::promise:
std::function<std::future<String> (String)> binding = [getter](String context) {
std::promise<String> p;
p.set_value(getter(contex));
return p.get_future();
};
Or using std::async:
std::function<std::future<String> (String)> binding = [getter](String context) {
return std::async(std::launch::deferred, getter, contex);
};
The right answer is to write your own make_ready_future (right out of std::experimantal). std::promise is about the only way I know of to produce a ready future: async produces non-ready futures.
This takes a value, and produces a future of that value, with some fancy stuff involving reference wrappers (which you can optionally skip).
A proposal to add it in C++1z exists, so by basing your own version off its interface, you can semi future-proof your code. Plus, as an audited design, it will suck less than your own.
Once you have it written:
template<class F>
auto futuristic_wrapper( F&& f ) {
return [f=std::forward<F>(f)](auto&&...args){
return make_ready_future( f( decltype(args)(args)... ) );
};
}
in C++11 you'd have to write a class to replace the lambda:
template<class F>
struct futurize {
F f;
template<class...Args>
operator()(Args&&...args)const->
delctype(make_ready_future(f(std::forward<Args>(args)...)))
{ return make_ready_future(f(std::forward<Args>(args)...)); }
};
template<class F>
auto futuristic_wrapper( F&& f )->
futurize< typename std::decay_t<F>::type >
{
return {std::forward<F>(f)};
}
which is annoying, but mostly a mechanical transformation.
This doesn't actually produce a std::function< future<R>(Args...) >, but it will return something convertible to that. No need to type erase if we don't need to after all.
You can put "your own version of to-be-standardized stuff" you steal from std::experimantal in a namespace like notstd. Always use it with notstd:: (never using namespace notstd;, and not using notstd::make_ready_future; as that risk behavior changes when the type is added to std) to be clear to later users that this is NOT the standard version of these objects.
Hello Guys so i want to code something in C++ that i have for C# but as there is no params object in C++ i need some help :P
Ok, so here's what i want to do:
static Int32 Procedure(UInt32 address, params Object[] parameters)
{
Int32 length = parameters.Length;
Int32 index = 0;
UInt32 count = 0;
UInt32 Strings = 0;
UInt32 Single = 0;
UInt32 Array = 0;
while (index < length)
{
if (parameters[index] is Int32)
{
WriteInt32(0x10050000 + (count * 4), (Int32)parameters[index]);
count++;
}
else if(paramaters[index] is String){ }.... // Thats just one thing i wanna use.. i've got more
..........
..........
}
return ReadInt32(0x000000);
}
so i need to figure out what type the parameter is + i wanna use an unknown amount of arguments and i have no idea how i would do this xD
I hope its clear and hopefully someone can Help me :3
Thx, Nico!
You can achieve something similar in C++ with variadic templates. Note that since C++ has no runtime reflection, it's not possible to dynamically get the type of any value: it can only be done at compile-time. Importantly, this also means that you cannot build a parameter list at runtime and pass it to the function without rolling out your own stuff to do it.
It is also arguably much more complicated than a C# equivalent (but then again, if C++ had all the strengths of C# with no weaknesses of itself, nobody would be using C#).
There may be other patterns, but the one I usually use looks like this (example with a print function):
template<typename... T>
void print_all_values(int value, T... values)
{
printf("%i ", value);
print_all_values(values...);
}
template<typename... T>
void print_all_values(double value, T... values)
{
printf("%g ", value);
print_all_values(values...);
}
template<typename... T>
void print_all_values(const char* value, T... values)
{
printf("%s ", value);
print_all_values(values...);
}
template<typename Unknown, typename... T>
void print_all_values(Unknown&& value, T... values)
{
printf("(can't print) ");
print_all_values(values...);
}
void print_all_values() {}
print_all_values(4, "hello world", 5.2, nullptr);
// prints: "4 hello world 5.2 (can't print)"
What happens here:
template<typename... T>
void print_all_values
This tells the compiler to create a distinct version of print_all_values for each different parameter type sequences it finds in my program.
void print_all_values(int value, T... values)
void print_all_values(double value, T... values)
void print_all_values(const char* value, T... values)
These differentiate the call per the first parameter. The idea here is that the function will only print its first parameter, then recursively call the template version with the remaining parameters:
{
printf("%s ", value);
print_all_values(values...);
}
At the end of the recursion chain, each parameter has been printed.
For my example print_all_values(4, "hello world", 5.2, nullptr), this is basically what would happen:
print_all_values(4, "hello world", 5.2, nullptr) -> the compiler uses print_all_values(4, ...), at runtime it'll do printf("%i", value), and the call at the end of the function becomes:
print_all_values("hello world", 5.2, nullptr) -> the compiler uses print_all_values("hello world", ...), at runtime it'll do printf("%s", value), and then:
print_all_values(5.2, nullptr) -> the compiler uses print_all_values(5.2, ...), printf("%g", value), then:
print_all_values(5.2, nullptr) -> the compiler can't find a suitable overload, so it falls back to the print_all_values(Unknown&& value, T... values) overload, does "(can't print)", and creates a call to print_all_values(), which does nothing.
The last overload:
template<typename Unknown, typename... T>
void print_all_values(Unknown&& value, T... values)
tells the compiler how handle any unknown type (in this case by printing (can't print)). Without this overload, we'd get a compile-time error if we tried to print an unknown type (because it all happens at compile-time, remember).
Did you already try a variadic template declaration like given in the following sample?
template<typename... Args>
static int32_t Procedure(uint32_t address, Args&&... parameters) {
// ...
}
C++ allows you to write functions accepting any number of parameters in the form of variadic template functions:
template<typename... ARGS>
void f( ARGS... args )
{
}
In that example, ARGS and args denote what is known as variadic packs. Neither are a template parameter or an function parameter, are just something that represents a set of template parameters, and a set of function parameters (Respectively).
So that are not parameters, are parameter packs, and then them cannot be manipulated directly. To use the content of a variadic pack, you have to expand the pack with an ellipsis.
Consider the example above: template<typename... ARGS> declares a variadic template with a variadic-pack named ARGS which represents a set of type template parameters.
In the next line, we expand that pack (ARGS...) to use that types as the types of the function argumments. That generates the variadic pack of function argumments args.
To use that argumments inside the function, you should expand args too. Since a pack is just a indetermined set of argumments, you can only use it in contexts where you use the hole set of argumments, in other words, you cannot access directly an specific element of the pack. For example:
template<typename... ARGS>
void f( ARGS... args )
{
f( args... ); //We call f() expanding the args pack of function parameters
//and passing the set of parameters to the function.
}
If you need to traverse the set of parameters in a pack (Which you would do in C# using the subscript operator on the params), you have to use the functional programming way of pattern matching and head-tail recursive list traversing:
template<typename HEAD , typename... TAIL>
void print( const HEAD& head , const TAIL&... tail )
{
std::cout << head << std::endl; //Do something with the head (Which is a
//normal function parameter)
print( tail... ); //Pass the tail to the next call
}
Note that function expects at least one parameter (A variadic template could be empty, but print() has one non-variadic parameter) . You should provide an overload with no parameters to act as base case (The case when there is no more argumments in the argumments list):
void print()
{
//Base case. Does nothing.
}
Now consider the signature of the print() function: Is a function which can take any number of parameters of any combination of types. In contrast to the C# (And Java) approach, storing the parameters in an array of an universal base class, and rely on polymorphism and casting), the C++ approach uses a statically-typed alternative, where the type of each function parameter is well determined at compile time.
I want to do for example:
#define macro(a) foo( _blah_, *(dword*)(&a) );
#define macro(a,b) foo( _blah_, *(dword*)(&a) , *(dword*)(&b) );
#define macro(a,b,c) foo( _blah_, *(dword*)(&a) , *(dword*)(&b) , *(dword*)(&c) );
But of course with variable no. of arguments. I essentially want to wrap each argument indiviudally, not pass all the arguments as one __VA_ARGS__ block.
As any other sane person, I advise you to drop the macros, especially with C++11's variadic templates:
template<class T>
dword& make_dword(T& v){
return *reinterpret_cast<dword*>(&v);
}
template<class... Args>
void bar(Args&... args){
foo(_blah_, make_dword(args)...);
}
This should do the trick.
I need to mention that those reinterpret_casts look pretty dubious, though...
I have an application which has a lot of functions which go through all the elements of a menu toolbar.
The code looks like something like this:
subMenuDefaultMenuShortcuts( ui->fileMenu );
subMenuDefaultMenuShortcuts(ui->editMenu);
subMenuDefaultMenuShortcuts(ui->windowMenu);
subMenuDefaultMenuShortcuts(ui->helpMenu);
subMenuUpdateLabels(ui->fileMenu,hierarchy);
subMenuUpdateLabels(ui->editMenu,hierarchy);
subMenuUpdateLabels(ui->windowMenu,hierarchy);
subMenuUpdateLabels(ui->helpMenu,hierarchy);
It is possible i will change this implementation, or menus could have sub menus. Thus search and replacing code, is not only ugly, but also hardly readable and error prone.
ideally i whould want something like this:
OnAllMenus(functionName,params ...)
so my code whould look like:
OnAllMenus(subMenuUpdateLabels)
OnAllMenus(subMenuUpdateLabels,hierarchy)
OnAllMenus(someFunction,hierarchy,argument1,argument2)
I wanted to use macro, but their usage is not recommended.
Howerver using inline functions with function pointers seems to lead to some hardly readable code. (And i did not see any example with function pointers expecting variable number of arguments with a function).
Is there any better / cleaner way to do it without addind some overly complex unmaintanable code.
template<typename FuncPointer, typename ... Args>
void for_all_menus(FuncPointer func, Args ... args)
{
f(ui->foo,std::forward<Args>(args)...);
f(ui->bar,std::forward<Args>(args)...);
// etc
}
// use
for_all_menus(&subMenuLabel, hierarchy);
Pmr's answer, but variadic templates to stop the stupid boost::binds that will be scattered everywhere.
You can use boost::function and boost::bind.
template<typename Func>
void for_all_menus(Func f) {
f(ui->foo);
f(ui->bar);
// etc
}
// use
for_all_menus(boost::bind(subMenuLabel, _1, hierarchy));
// with variadic templates
template<typename Func, typename Args...>
struct for_all_menus {
Func f;
void operator()(Args&&... args) {
// umh, I always mess up the syntax
// you might want to double check this
f(ui->foo, std::forward<Args>(args)...);
}
};
template<typename F>
for_all_menus<F> make_for_all_menus(F f) { return for_all_menus<F>{f}; }
// use
auto f = make_for_all_menus(subMenuLabel);
f(hierarchy);
If you need something more dynamic simply replace the function
template with a function that takes a boost::function. Of course you
can also use the C++11 equivalents and lambdas.
If you want to get the list of menus into one place and use that list
in different places, I'd recommend Boost.Preprocessor. But you might
want to think twice before resorting to it.