Fabric methods list for different arguments count - c++

I have a such factories, which instantiate objects by passed template class name T:
template<class T>
class Factory0
{
public:
static void *Create(){ return new T(); }
};
template<class T, class Argument1>
class Factory1
{
public:
static void *Create( Argument1 &arg1 ){ return new T( arg1 ); }
};
And i need to do something like such:
map<string[ClassName], &factory] _builder;
...
template<class T>
Add(){
if( T derived from BaseClass ) _builder[T] = &factory1::Create
else if( T derived from BaseClass ) _builder[T] = &factory0::Create;
}
template<class T>
Create() {
return _builder[T]( (factory0) ? <nothing> : <some_argument> );
}

This is hard for two reasons:
Calling create with the wrong arguments can only be caught at runtime, so we need a bit of dynamic typing.
C++ really doesn't like casting function pointers. Or creating pointers to templated functions. Or generally doing anything complex with function pointers.
But it can be done:
#include<string>
#include<map>
#include<iostream>
using namespace std;
struct returnable {
// Put some interesting virtual functions here
};
struct foo : public returnable {
foo() {
cout << "defaulFoo" << endl;
}
foo(int x) {
cout << "Foo:" << x << endl;
}
};
struct bar : public returnable {
bar(char a, char b){
cout << "bar:" << a << "," << b << endl;
}
};
template<typename... ARGS>
struct newmakerbase {
virtual returnable* make(ARGS... args) = 0;
};
template<typename OUT, typename... ARGS>
struct newmaker : public newmakerbase<ARGS...> {
virtual returnable* make(ARGS... args) {
return new OUT(args...);
}
};
// Boost might provide a neater version of this
int nextId = 0;
template<typename... T>
struct typeId {
static const int id;
};
template<typename... T>
const int typeId<T...>::id = nextId++;
map<string,void*> builders;
map<string,int> argtypes;
template<typename OUT, typename... ARGS>
void registerClas(string name) {
builders[name] = static_cast<void*>(new newmaker<OUT,ARGS...>());
argtypes[name] = typeId<ARGS...>::id;
}
template<typename... ARGS>
returnable* create(string name, ARGS... args) {
int argsgiven = typeId<ARGS...>::id;
if (argsgiven != argtypes[name]) {
// TODO: maybe throw an exception or something?
return NULL;
}
newmakerbase<ARGS...>* builder = static_cast<newmakerbase<ARGS...>*>(builders[name]);
return builder->make(args...);
}
main() {
registerClas<foo>("defaultFoo");
registerClas<foo,int>("foo");
registerClas<bar,char,char>("bar");
returnable* a = create("defaultFoo");
returnable* b = create("foo", 42);
returnable* c = create("foo", 'a', 'b'); // returns NULL
returnable* d = create("foo", 42.0); // also returns NULL
returnable* e = create("bar", 'c', 'd');
cout << a << " " << b << " " << c << " " << d << " " << e << endl;
}

Related

Choose C++ template at runtime

Is there any way to achieve the functionality of below code without creating the mapping between strings and classes manually?
template<class base, typename T>
base* f(const std::string &type, T &c) {
if(type == "ClassA") return new ClassA(c);
else if(type == "ClassB") return new ClassB(c);
// many more else if...
return nullptr;
}
All classes looks something like this:
class ClassA: public BaseClass {
public:
std::string label="ClassA";
...
};
And we can use it as:
BaseClass *b = f<BaseClass>("ClassA", DifferentObject);
Each new class results in a new if else line of code. Is there any way to automate this so f function "updates" itself when new supported class is added? The solution must work for C++11.
A possible macro:
#include <memory>
#include <string>
class BaseClass {};
class ClassA : public BaseClass {
public:
std::string label = "ClassA";
explicit ClassA(int /*unused*/) {}
};
class ClassB : public BaseClass {
public:
std::string label = "ClassB";
explicit ClassB(int /*unused*/) {}
};
template<class base, typename T>
auto f(const std::string &type, T c) -> std::unique_ptr<base> {
#define CASE(NAME) \
if (type == "NAME") { \
return std::unique_ptr<base>(new NAME(c)); \
}
CASE(ClassA)
CASE(ClassB)
//...
#undef CASE
return nullptr; // Statement at the end needed for last else!
}
auto main() -> int {
auto b = f<BaseClass>("ClassA", 0);
}
Also use unique_ptr since memory managing raw pointers are EVIL.
In that case if the class name is equal to the string, you can simplify your code with the following macro:
#define STRING_TO_CLASS (className) if(type == "className") return new className(c);
template<class base, typename T>
base* f(const std::string &type, T &c) {
STRING_TO_CLASS(ClassA)
STRING_TO_CLASS(ClassB)
return nullptr;
}
Personally I hate macros, but it disturbs only me. However, at compile time, the following code wil be generated, after the macros are resolved.
template<class base, typename T>
base* f(const std::string &type, T &c) {
if(type == "ClassA") return new ClassA(c);
if(type == "ClassB") return new ClassB(c);
return nullptr;
}
As you see, in the end only the else keyword is removed. Also, you need to modify your code if a new class is added.
You could use the registry pattern like this:
#include <map>
#include <functional>
#include <string>
template< typename T, typename X >
using Factory = std::function< T* ( X& ) >;
template< typename Base, typename X >
struct Registry {
using Map = std::map<std::string,Factory<Base,X> >;
static Map registry;
template< typename T >
struct Register {
Register( const std::string& name ) {
registry[ name ] = []( X& x ) -> T* { return new T(x); };
}
};
};
template< typename Base, typename X >
Base* factory(const std::string &type, X &c ) {
auto it = Registry<Base,X>::registry.find( type );
if ( it!=Registry<Base,X>::registry.end() ) {
return (it->second)(c);
}
return nullptr;
}
struct X {};
struct A {
A( X& x ) {};
virtual ~A() {}
};
struct B : public A {
B( X& x ) : A(x) {};
};
struct C : public A {
C( X& x ) : A(x) {};
};
struct D : public B {
D( X& x ) : B(x) {};
};
// Register class
template<> Registry<A,X>::Map Registry<A,X>::registry{};
Registry<A,X>::Register<B> regB( "B" );
Registry<A,X>::Register<C> regC( "C" );
Registry<A,X>::Register<D> regD( "D" );
#include <iostream>
int main() {
X x;
A* ptr = factory<A,X>( "B", x );
B* bptr = dynamic_cast<B*>( ptr );
if ( bptr!= nullptr ) {
std::cout << "Success!" << std::endl;
return 0;
}
std::cout << "Failed!" << std::endl;
return 1;
}
The correct pattern to use here is the "Abstract Factory" pattern.
Maybe you can look it up.
To give you and idea (and not more), what is possible, I will show you the below code, which even accepts constructors with different signature.
#include <iostream>
#include <map>
#include <utility>
#include <any>
// Some demo classes ----------------------------------------------------------------------------------
struct Base {
Base(int d) : data(d) {};
virtual ~Base() { std::cout << "Destructor Base\n"; }
virtual void print() { std::cout << "Print Base\n"; }
int data{};
};
struct Child1 : public Base {
Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "\n"; }
virtual ~Child1() { std::cout << "Destructor Child1\n"; }
virtual void print() { std::cout << "Print Child1: " << data << "\n"; }
};
struct Child2 : public Base {
Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "\n"; }
virtual ~Child2() { std::cout << "Destructor Child2\n"; }
virtual void print() { std::cout << "Print Child2: " << data << "\n"; }
};
struct Child3 : public Base {
Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "\n"; }
virtual ~Child3() { std::cout << "Destructor Child3\n"; }
virtual void print() { std::cout << "Print Child3: " << data << "\n"; }
};
using UPTRB = std::unique_ptr<Base>;
template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }
// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
std::map<Key, std::any> selector;
public:
Factory() : selector() {}
Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}
template<typename Function>
void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
Object create(Key key, Args ... args) {
if (selector.find(key) != selector.end()) {
return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
}
else return nullptr;
}
};
int main()
{
// Define the factory with an initializer list
Factory<int, UPTRB> factory{
{1, createClass<Child1, int, std::string>},
{2, createClass<Child2, int, char, long>}
};
// Add a new entry for the factory
factory.add(3, createClass<Child3, int, long, char, std::string>);
// Some test values
std::string s1(" Hello1 "); std::string s3(" Hello3 ");
int i = 1; const int ci = 1; int& ri = i; const int& cri = i; int&& rri = 1;
UPTRB b1 = factory.create(1, 1, s1);
UPTRB b2 = factory.create(2, 2, '2', 2L);
UPTRB b3 = factory.create(3, 3, 3L, '3', s3);
b1->print();
b2->print();
b3->print();
b1 = factory.create(2, 4, '4', 4L);
b1->print();
return 0;
}

Is there a way to pass a void function with any type and amount of arguments as an argument in a method and store it in a data member? (C++)

I ran into a problem while passing a function as a parameter in a method. My problem is that I want to be able to pass any void function with any type and amount of arguments and then store it in a data member. What I currently do is an overload for a void function without arguments and an overload for a void function with a vector argument of type std::any and then add an extra parameter for the vector. Here is an example of what I did:
typedef void (*FunctionT1)();
typedef void (*FunctionT2)(std::vector<std::any>);
class ExampleClass {
public:
void saveFunction(FunctionT1 f) {
emptyFunction = f;
}
void saveFunction(FunctionT2 f, std::vector<std::any> args) {
vectorFunction = f;
vectorFunctionArgs = args;
}
private:
FunctionT1 emptyFunction;
FunctionT2 vecotorFunction;
std::vector<std::any> vectorFunctionArgs;
}
Now this works and I'm able to do what I want but it's clearly a pretty bad solution. Is there a way to do this in an other way? (I was thinking of template packs but couldn't figure out how those would work)
From what I understand, you want to call a function void(), where caller might register other function type with bind parameters. You might do it with std::function:
class ExampleClass {
public:
void saveFunction(std::function<void()> f) {
this->f = f;
}
void call() { f(); }
private:
std::function<void()> f;
};
with usage
void foo();
void bar(std::vector<std::any>);
std::vector<std::any> v;
ExampleClass ex;
ex.SaveFunction(&foo); ex.call(); // foo();
ex.SaveFunction([&]() { bar(v); }); ex.call(); // bar(v);
// You might capture by copy/move if you prefer (instead of by reference)
I would like to show to you an example with an abstract factory.
With the factory pattern we have normally the problem, that all contstructors should have the same signature. But often we want to use functions with different parameter sets.
If you look in the below example, I can add functions with any number of parameters to the factory.
I know that this is not exactly what you want, but it may give you a hint on how to implement your own functionality.
#include <iostream>
#include <map>
#include <utility>
#include <any>
// Some demo classes ----------------------------------------------------------------------------------
struct Base {
Base(int d) : data(d) {};
virtual ~Base() { std::cout << "Destructor Base\n"; }
virtual void print() { std::cout << "Print Base\n"; }
int data{};
};
struct Child1 : public Base {
Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "\n"; }
virtual ~Child1() { std::cout << "Destructor Child1\n"; }
virtual void print() { std::cout << "Print Child1: " << data << "\n"; }
};
struct Child2 : public Base {
Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "\n"; }
virtual ~Child2() { std::cout << "Destructor Child2\n"; }
virtual void print() { std::cout << "Print Child2: " << data << "\n"; }
};
struct Child3 : public Base {
Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "\n"; }
virtual ~Child3() { std::cout << "Destructor Child3\n"; }
virtual void print() { std::cout << "Print Child3: " << data << "\n"; }
};
using UPTRB = std::unique_ptr<Base>;
template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }
// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
std::map<Key, std::any> selector;
public:
Factory() : selector() {}
Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}
template<typename Function>
void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
Object create(Key key, Args ... args) {
if (selector.find(key) != selector.end()) {
return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
}
else return nullptr;
}
};
int main()
{
Factory<int, UPTRB> factory{
{1, createClass<Child1, int, std::string>},
{2, createClass<Child2, int, char, long>}
};
factory.add(3, createClass<Child3, int, long, char, std::string>);
// Some test values
std::string s1(" Hello1 "); std::string s3(" Hello3 ");
int i = 1; const int ci = 1; int& ri = i; const int& cri = i; int&& rri = 1;
UPTRB b1 = factory.create(1, 1, s1);
UPTRB b2 = factory.create(2, 2, '2', 2L);
UPTRB b3 = factory.create(3, 3, 3L, '3', s3);
b1->print();
b2->print();
b3->print();
b1 = factory.create(2, 4, '4', 4L);
b1->print();
return 0;
}
From reading the question and going through the comments, this is what I think best suits your problem,
#include <vector>
class ExampleClass {
public:
ExampleClass() = default;
/**
* Save a function pointer.
*
* #param Function: The function poitner.
* #return The index of the function.
*/
template<class Return = void, class... Args>
size_t SaveFunction(Return(*Function)(Args... args))
{
mFunctions.insert(mFunctions.end(), Function);
return mFunctions.size() - 1;
}
/**
* Call a saved function.
*
* #tparam Return: The return type of the function.
* #param index: The index of the function.
* #param args: The arguments the function requires.
* #return The return of the function.
*/
template<class Return = void, class... Args>
Return CallFunction(size_t index, const Args&... args)
{
typedef Return(*Function)(Args...);
return reinterpret_cast<Function>(mFunctions[index])(args...);
}
private:
std::vector<void*> mFunctions;
};
And then you can save and call any function as so,
void Function() { std::cout << "Hello World\n"; }
void Add(int x, int y) { std::cout << x + y << std::endl; }
int main()
{
ExampleClass c;
size_t f1 = c.SaveFunction(Function);
size_t f2 = c.SaveFunction(Add);
c.CallFunction(f1);
c.CallFunction(f2, 1, 2);
}
This works with any function with any amount of arguments.
Note: If the return type is always gonna be a void, you can replace the Return with void.

C++: Generic factory that can call any constructor?

I'm trying to write a factory class which will have a standard interface that looks like this:
Register<MyBase, MyDerived> g_regDerived("myderived"); // register to factory
now calling:
auto* d = Factory<MyBase>::instance().create("myderived", 1, 2, 3);
will invoke the constructor MyDerived(1,2,3) and return a pointer to the created object
This sounds like something that should be possible with C++11 but I could not figure out how to do it.
Starting from a standard type-erasure factory:
template<typename BaseT>
class Factory {
public:
static Factory* instance() {
static Factory inst;
return &inst;
}
template<typename T>
void reg(const string& name) {
m_stock[name].reset(new Creator<T>);
}
BaseT* create(const string& name) {
return m_stock[name]->create();
}
private:
struct ICreator {
virtual BaseT* create() = 0;
};
template<typename T>
struct Creator : public ICreator {
virtual BaseT* create() {
return new T;
}
};
std::map<string, std::unique_ptr<ICreator>> m_stock;
};
template<typename BaseT, typename T>
class Register {
public:
Register(const QString& name) {
Factory<BaseT>::instance()->reg<T>(name);
}
};
The problem here is fact that once you erase the type of the created object, you can no longer pass arbitrary template forwarded arguments since you need to pass them through a virtual function.
The answer to this question:
How to pass a function pointer that points to constructor?
talks about something similar but the answer there is to go through a function which is specific for every derived class. I want to use the class constructor directly and not have to write a create() function.
I don't know why your aversion to writing a create() function. So here is one that I implemented.
#include <iostream>
#include <utility>
using namespace std;
class C
{
public:
virtual char const* whoAmI() const = 0;
};
class A : public C
{
public:
A(int a1)
{
cout << "A(" << a1 << ")" << endl;
}
A(float a1)
{
cout << "A(" << a1 << ")" << endl;
}
virtual char const* whoAmI() const override
{
return "A";
}
};
class B : public C
{
public:
B(int a1)
{
cout << "B(" << a1 << ")" << endl;
}
B(float a1)
{
cout << "B(" << a1 << ")" << endl;
}
virtual char const* whoAmI() const override
{
return "B";
}
};
template<typename BASET>
class Factory
{
public:
// could use a is_base type trait test here
template <typename T, typename...ARGs>
static BASET* create(ARGs&&...args)
{
return new T(forward<ARGs>(args)...);
}
};
int main()
{
Factory<C> factory;
C* a = factory.create<A>(1);
C* b = factory.create<B>(1.0f);
cout << a->whoAmI() << endl;
cout << b->whoAmI() << endl;
return 0;
}
NOTE: I didn't do everything that yours does, I merely implemented the create function. I leave the final implementation up to you.
This uses perfect forwarding to enable a varidict template to pass any number of parameters to a constructor. Your register function can then store a function pointer of a particular template instance, for a particular parameter set.
EDIT
I forgot to use the appropriate forward<ARGs>(args)... call to implement perfect forwarding. It has now been added.
As for you thinking that this is not useful, here is the full implementation of your factory using perfect forwarding and varidict templates allowing a specific number of parameters of particular types for a particular factory instance:
#include <string>
#include <map>
#include <memory>
#include <utility>
#include <iostream>
using namespace std;
template<typename BaseT, typename...ARGs>
class Factory {
public:
static Factory* instance() {
static Factory inst;
return &inst;
}
template<typename T>
void reg(const string& name) {
m_stock[name].reset(new Creator<T>);
}
BaseT* create(const string& name, ARGs&&...args) {
return m_stock[name]->create(forward<ARGs>(args)...);
}
private:
struct ICreator
{
virtual BaseT* create(ARGs&&...) = 0;
};
template<typename T>
struct Creator : public ICreator {
virtual BaseT* create(ARGs&&...args) override
{
return new T(forward<ARGs>(args)...);
}
};
std::map<string, std::unique_ptr<ICreator>> m_stock;
};
template<typename BaseT, typename T, typename...ARGs>
class Register {
public:
Register(const string& name) {
auto instance = Factory<BaseT, ARGs...>::instance();
instance->template reg<T>(name);
}
};
struct C
{
virtual char const * whoAmI() const = 0;
};
struct A : public C
{
A(int a1, int a2)
{
cout << "Creating A(" << a1 << ", " << a2 << ")" << endl;
}
virtual char const * whoAmI() const override
{
return "A";
}
};
struct B : public C
{
B(int b1, int b2)
{
cout << "Creating B(" << b1 << ", " << b2 << ")" << endl;
}
B(int b1, int b2, int b3)
{
cout << "Creating B(" << b1 << ", " << b2 << ", " << b3 << ")" << endl;
}
virtual char const * whoAmI() const override
{
return "B";
}
};
typedef int I;
Register<C, A, I, I> a("a");
Register<C, B, I, I> b("b");
Register<C, B, I, I, I> b3("b");
int main()
{
C* a = Factory<C, I, I>::instance()->create("a", 1, 2);
C* b = Factory<C, I, I>::instance()->create("b", 3, 4);
C* b3 = Factory<C, I, I, I>::instance()->create("b", 5, 6, 7);
cout << "I am a " << a->whoAmI() << endl;
cout << "I am a " << b->whoAmI() << endl;
cout << "I am a " << b3->whoAmI() << endl;
return 0;
}
Is that what you want? If you don't want to deal with the function parameters, use a helper template function to deduce them for you like so:
template <typename BaseT, typename...ARGs>
BaseT* create(const string& name, ARGs&&...args)
{
return Factory<C, ARGs...>::instance()->create(name, forward<ARGs>(args)...);
}
int main()
{
C* a = create<C>("a", 1, 2);
C* b = create<C>("b", 3, 4);
C* b3 = create<C>("b", 3, 4, 5);
cout << "I am a " << a->whoAmI() << endl;
cout << "I am a " << b->whoAmI() << endl;
cout << "I am a " << b3->whoAmI() << endl;
return 0;
}
Which has the added bonus of allowing multiple constructor signatures available through the apparent single function API (it only looks like one, but is actually N where N is the number of different signatures you allow). This all can be viewed through this online demo.
You'll still need to use the same registration as I depicted before though, which could be shortened by way of a macro.
If this is still not what you want, then add additional detail to your question.

C++ function decorator

I am looking for a way to decorate functions or lambdas in C++. The goal is to do something before and after the function call. As I've seen the closest thing to use is std::function but it needs to have the types of its arguments.
class FunctionDecorator
{
public:
FunctionDecorator( std::function func )
: m_func( func )
void operator()()
{
// do some stuff prior to function call
m_func();
// do stuff after function call
}
private:
std::function m_func;
};
It would be great if by template type could be used in std::function and it could deduce it somehow when i pass pointer to a function or a result from std::bind.
Is such thing possible in C++.
Hmm. I may or may not have gone overkill.
#include <type_traits>
#include <utility>
#include <iostream>
template <class T>
struct RetWrapper {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args)
: val(std::forward<Tfunc>(func)(std::forward<Targs>(args)...)) {}
T &&value() { return static_cast<T &&>(val); }
private:
T val;
};
template <>
struct RetWrapper<void> {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args) {
std::forward<Tfunc>(func)(std::forward<Targs>(args)...);
}
void value() {}
};
template <class Tfunc, class Tbefore, class Tafter>
auto decorate(Tfunc &&func, Tbefore &&before, Tafter &&after) {
return [
func = std::forward<Tfunc>(func),
before = std::forward<Tbefore>(before),
after = std::forward<Tafter>(after)
] (auto &&... args) -> decltype(auto) {
before(std::forward<decltype(args)>(args)...);
RetWrapper<std::result_of_t<Tfunc(decltype(args)...)>> ret(
func, std::forward<decltype(args)>(args)...
);
after(std::forward<decltype(args)>(args)...);
return ret.value();
};
}
/*
* Tests
*/
float test1(float a, float b) {
std::cout << "Inside test1\n";
return a * b;
}
void test2() {
std::cout << "Inside test2\n";
}
int i = 0;
int &test3() {
return i;
}
int main() {
auto test1Deco = decorate(
test1,
[] (float a, float b) {
std::cout << "Calling test1 with " << a << " and " << b << '\n';
},
[] (float a, float b) {
std::cout << "Called test1 with " << a << " and " << b << '\n';
}
);
float c = test1Deco(3.5f, 5.1f);
std::cout << "Yields " << c << '\n';
auto test2Deco = decorate(
test2,
[] () {
std::cout << "Calling test2\n";
},
[] () {
std::cout << "Called test2\n";
}
);
test2Deco();
auto test3Deco = decorate(
test3,
[] () {
std::cout << "Calling test3\n";
},
[] () {
std::cout << "Called test3\n";
}
);
auto &i2 = test3Deco();
i2 = 42;
std::cout << "Global i = " << i << '\n';
return 0;
}
Output :
Calling test1 with 3.5 and 5.1
Inside test1
Called test1 with 3.5 and 5.1
Yields 17.85
Calling test2
Inside test2
Called test2
Calling test3
Called test3
Global i = 42
Just go full template, without std::function:
template< typename Func >
class FunctionDecorator
{
public:
FunctionDecorator( Func func )
: m_func( std::move(func) )
{}
void operator()()
{
// do some stuff prior to function call
m_func();
// do stuff after function call
}
private:
Func m_func;
};
template< typename Func >
FunctionDecorator<Func> decorate(Func func) {
return FunctionDecorator<Func>(std::move(func));
}
[Note: edited a few hours after initial posting]
This perhaps isn't exactly what the OP was looking for, but it's still relevant and hopefully useful to others looking for answers.
Let's say you have a couple of functions that have slightly different signatures:
void foo1(int& x){ cout << "foo1(" << x << ")\n";}
void foo2(double& x){ cout << "foo2(" << x << ")\n";}
and you'd like to wrap a decorator around them both so as to standardise their signatures, e.g. turn them both into void (*)(int).
Then you could do the following:
template<typename Q, void (*foo_p)(Q&)>
void wrapped(int x){
Q v = 42.2 + x;
foo_p(v);
}
int main(){
using foo_t = void (*)(int); // we coerce foo1 and foo2 into this type
foo_t k_int = wrapped<int, foo1>;
foo_t k_double = wrapped<double, foo2>;
k_int(-1); //cout: foo1(41)
k_double(-1); //cout: foo2(41.2)
return 0;
}
Using the example main I've given here, clang inlines the whole thing, which is a good sign but not quite what we wanted to check. If you make the example a bit more complex (see live here) you can see that it does indeed inline everything within each wrapper, i.e. foo1 and foo2 don't exist in standalone form, only in wrapped form.
Originally, I use a lambda in addition to the wrapped<...> template (making use of the fact that lambdas with no-capture can be converted to function pointers) but then I realized that the extra wrapping was redundant in this case.
This method should work for passing anything known at run time, which could even include a pointer to a mutable global (although that's getting pretty messy).
#include <iostream>
#include <string>
using namespace std;
template <typename TResult, typename TParams>
class CClassGenerique
{
typedef TResult (*uneFonction) (TParams);
public :
CClassGenerique (uneFonction f){ m_function = f; }
void operator () (TParams t) { m_function (t); }
private :
uneFonction m_function;
};
template <typename TResult, typename TParams>
TResult BasicFunction (TParams p)
{
TResult t=0;
std::cout<<" Value = " << p <<endl;
return t;
}
int main (int argc, char* argv[])
{
CClassGenerique<int, int> c1 (BasicFunction<int, int>);
CClassGenerique<int, char*> c2 (BasicFunction<int, char*>);
CClassGenerique<char*, char*> c3 (BasicFunction<char*, char*>);
c1(3);
c2("bonsoir");
c3("hello");
return 0;
}

Strange? behaviour of cout

Why executing this code:
// DefaultAny.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <exception>
using std::cout;
template<class T>
struct NoReturnPolicy
{
static void calculate(T& result, const T& source)
{
result = source;
}
};
template<class T>
struct ReturnPolicy
{
static T& calculate(T& result, const T& source)
{
result = source;
return result;
}
};
template<class T>
struct ThrowPolicy
{
static void check(T* ptr)
{
cout << "ThrowPolicy";
struct Nullptr: public std::exception{};
if(!ptr)
{
throw Nullptr("Nullptr not allowed");
}
}
};
template<class T>
struct NoThrowPolicy
{
static T* check(T* ptr)
{
cout << "NoThrowPolicy";
if(!ptr)
{
return nullptr;
}
else
{
return ptr;
}
}
};
/*
If pointer already points at
something no assignement is being done
*/
template<class T, class ThrowingPolicy>
struct NoAssignPolicy
{
static T* check(T* dest,const T*const src)
{
cout << "NoAssignPolicy";
if (!ThrowPolicy::check(dest))
{
dest = operator new(sizeof(T));
new (dest) T(*src);
}
}
};
template<class T,class ThrowingPolicy>
struct NoCheckPolicy
{
static void check(T* p)
{
cout << "NoCheckPolicy";
}
};
template<class T,class ThrowingPolicy>
struct CheckPolicy
{
static void check(T* p)
{
cout << "CheckPolicy";
ThrowingPolicy::check(p);
}
};
template<
class T,
class ThrowingPolicy = NoThrowPolicy<T>,
class CheckingPolicy = NoCheckPolicy<T,ThrowingPolicy>,
class AssigningPolicy = NoAssignPolicy<T,ThrowingPolicy>,
class ReturningPolicy = NoReturnPolicy<T>
>
struct BreadSlicer
{
BreadSlicer()
{
cout << "Type: " << typeid(T).name() << '\n';
cout << "ThrowingPolicy: " << ThrowingPolicy::check(0) << '\n'; //
//<<<---------The second call to cout makes output on my console:
//NoThrowPolicy:"NoSpace"ThrowingPolicy:"Space"000000
}
};
//The words NoSpace and Space do not actually appear in my console ;) and they are in the opposite order.
int _tmain(int argc, _TCHAR* argv[])
{
BreadSlicer<int> a;
return 0;
}
See comments in first struct above main.
This is the result of unspecified behavior. If you have:
cout << a() << b() << c() << endl;
The order of execution of a, b, and c is not defined (yes, their results are added to the cout stream in a predictable order, but execution of the functions is not in defined order).
If your question is why "NoThrowPolicy" gets output before "ThrowingPolicy", the answer is that there's no sequence point guaranteeing an ordering for the call to ThrowingPolicy::check(0) and the call to operator<<(cout, "ThrowingPolicy: "). C++ is allowed to call those functions in either order.