I am trying to create some kind of event handler in c++. So I have got the following:
template<class W>
delegate<W>* bind(W* obj, void (W::*f)(char*))
{
return new delegate<W>(obj,f);
}
The delegate class and this function works perfectly. The problem is how to store the delegate object which with the bind function returns? I know that with boost and c++ 11 it is quite easy but how can I solve this without using them? I'm sure that it has to be possible because it was possible before these sophisticated things like boost and c++11.
(And they did it somehow in the boost as well).
So what I want to do:
class Test1
{
Test1(){}
~Test1(){}
template<class W>
bind(W* obj, void (W::*f)(char*))
{
myCallBack = new delegate<W>(obj,f);
}
private:
delegate * myCallBack; //this does not work because I have to define the template but I dont know it know it could be anything
}
class Test2
{
Test2()
{
Test1 t;
t.bind(this, &Test2::callit);
}
~Test2(){}
void callit(char*)
{
}
}
Ok, I understood what exactly you need. You need just a simple callback operator, with fixed calling signature.
This example demonstrates how it is done for your specific case :
#include <iostream>
#include <utility>
#include <type_traits>
#include <vector>
#include <algorithm>
struct Cb {
virtual ~Cb(){}
virtual void call(const char*) = 0;
};
template<class C>
struct CmCb : Cb {
CmCb( C& c_, void (C::*fn_)(const char*) ) : c(c_),fn(fn_)
{
}
virtual void call(const char* s) {
(c.*fn)(s);
}
C& c;
void (C::*fn)(const char*);
};
struct A {
void foo( const char* s ) {
std::cout<<s<<std::endl;
}
};
class Test1
{
public:
Test1(){}
~Test1(){delete cb;}
template<class W>
void bind(W* obj, void (W::*f)(const char*))
{
cb=new CmCb<W>(*obj,f);
}
void callit(const char* s ){
cb->call(s);
}
private:
Cb* cb;
};
int main()
{
Test1 t;
A a;
t.bind(&a, &A::foo );
t.callit("hey");
}
If you need more complex solution (generic signature) then you can use some kind of type erasure with boost::any.
There are indeed more sophisticated implementations for smart pointers than they were provided with the original standard (std::auto_ptr). But they're all involving a bit more complex concepts (regarding reference counting for shared pointers mainly). What's the hinder to use these?
If you need a more lightweight smart pointer implementation for a c++03 environment, Andrei Alexandrescu's Loki Library might be useful for you. I have managed to integrate it seamlessly for limited system environments at least (better and easier than using boost).
Don't even try to do this completely on your own, there are many many pitfalls ...
If you're able to enable c++11 standards, just use these!
Related
I used to define my template requirement through abstract class, e.g.
#include <iostream>
#include <random>
/// Generic interface
template<typename A, typename B>
struct Interface {
virtual A callback_A(const std::vector<A>& va) = 0;
virtual const B& callback_B() = 0;
};
/// Mixin style, used to "compose" using inheritance at one level, no virtual
struct PRNG_mt64 {
std::mt19937_64 prng;
explicit PRNG_mt64(size_t seed) : prng(seed) {};
};
/// Our implementation
template<typename A>
struct Implem :
public Interface<A, std::string>,
public PRNG_mt64 {
std::string my_string{"world"};
explicit Implem(size_t seed) : PRNG_mt64(seed) {}
A callback_A(const std::vector<A>& a) override { return a.front(); }
const std::string& callback_B() override { return my_string; }
};
/// Function using our type. Verification of the interface is perform "inside" the function
template<typename T>
void use_type(T& t) {
auto& strings = static_cast<Interface<std::string, std::string>&>(t);
std::cout << strings.callback_A({"hello"}) << " " << strings.callback_B() << std::endl;
auto& prng = static_cast<PRNG_mt64&>(t).prng;
std::uniform_real_distribution<double> dis(0.0, 1.0);
std::cout << dis(prng) << std::endl;
}
int main(int argc, char **argv) {
size_t seed = std::random_device()();
Implem<std::string> my_impl(seed);
use_type(my_impl);
}
One benefit of using the asbtract class is the clear specification of the interface, easily readable. Also, Implem has to confom to it (we cannot forget the pure virtual).
A problem is that the interface requirement is hidden in the static cast (that comes from my real use case where a composite "state" is used by several polymorphic components - each component can cast the state to only see what it needs to see). This is "solved" by concepts (see below).
Another one is that we are using the virtual mechanism when we have no dynamic polymorphism at all, so I would like to get rid of them. What is the best way to convert this "interface" into concept?
I came up with this:
#include <iostream>
#include <random>
/// Concept "Interface" instead of abstract class
template<typename I, typename A, typename B>
concept Interface = requires(I& impl){
requires requires(const std::vector<A>& va){{ impl.callback_A(va) }->std::same_as<A>; };
{ impl.callback_B() } -> std::same_as<const B&>;
};
/// Mixin style, used to "compose" using inheritance at one level, no virtual
struct PRNG_mt64 {
std::mt19937_64 prng;
explicit PRNG_mt64(size_t seed) : prng(seed) {};
};
/// Our implementation
template<typename A>
struct Implem : public PRNG_mt64 {
std::string my_string{"world"};
/// HERE: requires in the constructor to "force" interface. Can we do better?
explicit Implem(size_t seed) requires(Interface<Implem<A>, A, std::string>): PRNG_mt64(seed) {}
A callback_A(const std::vector<A>& a) { return a.front(); }
const std::string& callback_B() { return my_string; }
};
/// Function using our type. Verification of the interface is now "public"
template<Interface<std::string, std::string> T>
void use_type(T& t) {
std::cout << t.callback_A({"hello"}) << " " << t.callback_B() << std::endl;
auto& prng = static_cast<PRNG_mt64&>(t).prng;
std::uniform_real_distribution<double> dis(0.0, 1.0);
std::cout << dis(prng) << std::endl;
}
int main(int argc, char **argv) {
size_t seed = std::random_device()();
Implem<std::string> my_impl(seed);
use_type(my_impl);
}
Questions:
Is that actually the thing to do in the first place? I saw several posts on the internet explaning concepts, but they are always so shallow that I'm afraid I'll miss something regarding perfect forwarding, move, etc...
I used a requires requires clause to keep function arguments close to their usage (useful when having many methods). However, the "interface" information is now hard to read: can we do better?
Also, the fact that Implem implements the interface is now the part that is "hidden" inside the class. Can we make that more "public" without having to write another class with CRTP, or limiting the boilerplate code as much as possible?
Can we do better for the "mixin" part PRNG_mt64? Ideally, turning this into a concept?
Thank you!
Your pre-C++20 approach is pretty bad, but at least it sounds like you understand the problems with it. Namely, you're paying 8 bytes for a vptr when you don't need it; and then strings.callback_B() is paying the cost of a virtual call even though you could be calling t.callback_B() directly.
Finally (this is relevant, I promise), by funneling everything through the base-class reference strings, you're taking away Implem's ability to craft a helpful overload set. I'll show you a simpler example:
struct Interface {
virtual int lengthOf(const std::string&) = 0;
};
struct Impl : Interface {
int lengthOf(const std::string& s) override { return s.size(); }
int lengthOf(const char *p) { return strlen(p); }
};
template<class T>
void example(T& t) {
Interface& interface = t;
static_assert(!std::same_as<decltype(interface), decltype(t)>); // Interface& versus Impl&
int x = interface.lengthOf("hello world"); // wastes time constructing a std::string
int y = t.lengthOf("hello world"); // does not construct a std::string
}
int main() { Impl impl; example(impl); }
The generic-programming approach would look like this, in C++20:
template<class T>
concept Interface = requires (T& t, const std::string& s) {
{ t.lengthOf(s) } -> convertible_to<int>;
};
struct Impl {
int lengthOf(const std::string& s) override { return s.size(); }
int lengthOf(const char *p) { return strlen(p); }
};
static_assert(Interface<Impl>); // sanity check
template<Interface T>
void example(T& t) {
Interface auto& interface = t;
static_assert(std::same_as<decltype(interface), decltype(t)>); // now both variables are Impl&
int x = interface.lengthOf("hello world"); // does not construct a std::string
int y = t.lengthOf("hello world"); // does not construct a std::string
}
int main() { Impl impl; example(impl); }
Notice that there is no way at all to get back the "funneling" effect you had with the base-class approach. Now there is no base class, the interface variable itself is still statically a reference to an Impl, and calling lengthOf will always consider the full overload set provided by the Impl. This is a good thing for performance — I think it's a good thing in general — but it is radically different from your old approach, so, be careful!
For your callback_A/B example specifically, your concept would look like
template<class T, class A, class B>
concept Interface = requires (T& impl, const std::vector<A>& va) {
{ impl.callback_A(va) } -> std::same_as<A>;
{ impl.callback_B() } -> std::same_as<const B&>;
};
In real life I would very strongly recommend changing those same_ases to convertible_tos instead. But this code is already very contrived, so let's not worry about that.
In C++17 and earlier, the equivalent "concept" (type-trait) definition would look like this (complete working example in Godbolt). Here I've used a macro DV to shorten the boilerplate; I wouldn't actually do that in real life.
#define DV(Type) std::declval<Type>()
template<class T, class A, class B, class>
struct is_Interface : std::false_type {};
template<class T, class A, class B>
struct is_Interface<T, A, B, std::enable_if_t<
std::is_same_v<int, decltype( DV(T&).callback_A(DV(const std::vector<A>&)) )> &&
std::is_same_v<int, decltype( DV(T&).callback_B() )>
>> : std::true_type {};
I want to add delegates to my game engine. I'm used to them in c# and now I can't live without them.
I have seen several implementations here and on external sources but they are not multicast. The delegate is just allowed to store one listener at a time. Do anybody know of any good implementation in memory/performance terms with += and -= support? I have tried writting mine using variadic templates but I'm not there yet.
Edit: This is what I have come with until now:
template<typename ... Args>
class Delegate
{
public:
Delegate() =default;
~Delegate() = default;
template<typename U>
Delegate& operator += (const U &func)
{
_listeners.push_back(std::function<void(Args...)>(func));
return *this;
}
template<typename Class, typename Method>
Delegate& operator += (const std::function<void(Args...)> func)
{
_listeners.push_back(func);
return *this;
}
void operator() (Args... params)
{
for (auto listener : _listeners)
{
listener(params...);
}
}
private:
std::list<std::function<void(Args...)>> _listeners;
};
It is working really well. Here you can see how to use it:
Delegate<std::string> del;
del += std::bind(&GameScene::print, this, std::placeholders::_1);
del += [](const std::string& str) { log(str.c_str()); };
del("text");
I know I will use the std::bind version almost all the time because this is used in a event messaging system and instances will subscribe to the delegate using a class method (by class method I am not refering to static method but a method of the class). Is there anyway to improve the std::bind part? I think it is a bit ugly and annoying when you have to add some funcions with placeholders, etc...
Cheers.
Basically, a naive C++ 11 implementation could look like:
#include <vector>
#include <functional>
class Foo
{
public:
std::vector< std::function< void() > > onSomething;
};
int main( void )
{
Foo f;
f.onSomething.push_back( [&] { /* Do something... */ } );
f.onSomething.push_back( [&] { /* Do something else... */ } );
return 0;
}
Note the use of std::function, which allows to store lambdas in a vector.
You'll then be able to iterate through the vector, and execute each lambda.
Then, of course, operator overloading and thread safety if needed... But this should be trivial.
Problem in short:
How could one implement static if functionality, proposed in c++11, in plain c++ ?
History and original problem:
Recently I came up with a problem like this. I need a class Sender with an interface like
class Sender
{
void sendMessage( ... );
void sendRequest( ... );
void sendFile( ... );
// lots of different send methods, not important actually
}
In some cases I will need to create a DoubleSender, i.e. an instance of this class, which would call its methods twice, i.e. when calling, let's say, a sendMessage(...) method, the same message has to be sent twice.
My solutions:
First approach:
Have an isDouble member, and in the end of each method call make a check
sendMessage(...) { ... if( isDouble ) { sendMessage( ... ); }
Well, I don't want this, because actually I will need double posting very recently, and this part of code in time-critical section will be 98% passive.
Second approach:
Inherit a class DoubleSender from Sender, and implement its methods like:
void DoubleSender::sendMessage( ... )
{
Sender::sendMessage(...);
Sender::sendMessage(...);
}
Well, this is acceptable, but takes much space of unpleasant code (really much, because there are lots of different send.. methods.
Third approach:
Imagine that I am using c++11 :). Then I can make this class generic and produce the necessary part of code according to tempalte argument using static if:
enum SenderType { Single, Double };
template<SenderType T>
class Sender
{
void sendMessage(...)
{
// do stuff
static if ( T == Single )
{
sendMessage(...);
}
}
};
This is shorter, easier to read than previous solutions, does not generate additional code and... it's c++11, which I unfortunately cannot use in my work.
So, here is where I came to my question - how can I implement static if analog in c++ ? Also, I would appreciate any other suggestions about how to solve my original problem.
Thanks in advance.
Quoting #JohannesSchaubLitb
with my static_if that works on gcc one can do it :)
in some limited fashion
(see also here)
This trick involves a specific GCC interpretation of the specs on Lambdas in C++11. As such, it will (likely) become a defect report against the standard. This will lead to the trick no longer working in more recent version of GCC (it already doesn't work in 4.7).
See the comment thread below for some more details from Johanness
http://ideone.com/KytVv:
#include <iostream>
namespace detail {
template<bool C>
struct call_if { template<typename F> void operator<<(F) { } };
template<>
struct call_if<true> {
template<typename F>
void operator<<(F f) { f(); }
};
}
#define static_if(cond) detail::call_if<cond>() << [&]
template<bool C, typename T>
void f(T t) {
static_if(C) {
t.foo();
};
}
int main() {
f<false>(42);
}
Why not make the send implementation a policy of the sender class and use CRTP:
template<class Derived>
class SingleSenderPolicy
{
public:
template< class memFunc >
void callWrapperImpl(memFunc f, ...)
{
static_cast<Derived *>(this)->f(...);
}
};
template< class Derived >
class DoubleSenderPolicy
{
public:
template< class memFunc >
void callWrapperImpl(memFunc f, ...)
{
static_cast<Derived *>(this)->f(...);
static_cast<Derived *>(this)->f(...);
}
};
template< class SendPolicy>
class Sender : public SendPolicy< Sender >
{
public:
void sendMessage( ... )
{
// call the policy to do the sending, passing in a member function that
// acutally performs the action
callWrapperImpl( &Sender::sendMessageImpl, ... );
}
void doSomethingElse( ... )
{
callWrapperImpl( &Sender::doSomethingElseImpl, ... );
}
protected:
void sendMessageImpl(... )
{
// Do the sending here
}
void doSomethingElseImpl(... )
{
// Do the sending here
}
};
The public sendXXX functions in you class simply forward to the call wrapper, passing in a member function that implements the real functionality. This member function will be called according to the SendPolicy of the class. CRTP saves the use of bind to wrap the arguments and this pointer up with the member function to call.
With one function it doesn't really cut down on the amount of code, but if you have a lot of calls it could help.
Note: This code is a skeleton to provide a possible solution, it has not been compiled.
Note: Sender<DoubleSenderPolicy> and Sender<SingleSenderPolicy> are completely different types and do not share a dynamic inheritance relationship.
Most compilers do constant folding and dead code removal, so if you write a regular if statement like this:
enum SenderType { Single, Double };
template<SenderType T>
class Sender
{
void sendMessage(...)
{
// do stuff
if ( T == Single )
{
sendMessage(...);
}
}
};
The if branch will get removed when the code is generated.
The need for static if is when the statements would cause a compiler error. So say you had something like this(its somewhat psuedo code):
static if (it == random_access_iterator)
{
it += n;
}
Since you can't call += on non-random access iterators, then the code would always fail to compile with a regular if statement, even with dead code removal. Because the compiler still will check the syntax for before removing the code. When using static if the compiler will skip checking the syntax if the condition is not true.
std::string a("hello world");
// bool a = true;
if(std::is_same<std::string, decltype(a)>::value) {
std::string &la = *(std::string*)&a;
std::cout << "std::string " << la.c_str() << std::endl;
} else {
bool &la = *(bool*)&a;
std::cout << "other type" << std::endl;
}
I have several classes from 3rd party library similar to the class, StagingConfigDatabase, which requires to be destroyed after it is created. I am using a shared_ptr for RAII but would prefer to create the shared_ptr using a single line of code rather than using a seperate template functor as my example shows. Perhaps using lambdas? or bind?
struct StagingConfigDatabase
{
static StagingConfigDatabase* create();
void destroy();
};
template<class T>
struct RfaDestroyer
{
void operator()(T* t)
{
if(t) t->destroy();
}
};
int main()
{
shared_ptr<StagingConfigDatabase> pSDB(StagingConfigDatabase::create(), RfaDestroyer<StagingConfigDatabase>());
return 1;
}
I was considering something like:
shared_ptr<StagingConfigDatabase> pSDB(StagingConfigDatabase::create(), [](StagingConfigDatabase* sdb) { sdb->destroy(); } );
but that doesn't compile :(
Help!
I'll assume that create is static in StagingConfigDatabase because your initial code wouldn't compile without it. Regarding destruction, you can use a simple std::mem_fun :
#include <memory>
boost::shared_ptr<StagingConfigDatabase> pSDB(StagingConfigDatabase::create(), std::mem_fun(&StagingConfigDatabase::destroy));
What compiler are you using? Does it support C++0x features like lambdas? The following (which is basically the same as your example) compiles and works fine for me under MSVC 2010:
#include <iostream>
#include <memory>
struct X
{
static X *create()
{
std::cout << "X::create\n";
return new X;
}
void destroy()
{
std::cout << "X::destroy\n";
delete this;
}
};
int main()
{
auto p = std::shared_ptr<X>(X::create(), [](X *p) { p->destroy(); });
return 0;
}
By "works fine", I mean "outputs X::create followed by X::destroy".
I have a "generator" class that basically constructs its subclass. To use this thing I simply subclass it and pass it the correct parameters to build the object I want built. I want to serialize these things and there's no good reason to do it for each subclass since all the data is in the base. Here's what I've got as example:
#include <boost/serialization/serialization.hpp>
template < typename T >
struct test_base
{
// works...
//template < typename Archive >
//void serialize(Archive &, unsigned int const)
// {
//}
};
template < typename T >
void f(test_base<T> const&) {}
struct test_derived : test_base<int>
{
};
namespace boost { namespace serialization {
template < typename Archive, typename T >
void serialize(Archive &, test_base<T> &, unsigned int const)
{
}
}}
#include <boost/archive/binary_oarchive.hpp>
#include <sstream>
int main()
{
int x = 5;
test_derived d;
//boost::serialization::serialize(x, d, 54); // <- works.
std::ostringstream str;
boost::archive::binary_oarchive out(str);
out & d; // no worky.
}
I want the free version to work if possible. Is it?
Version above pukes up error about serialize not being a member of test_derived.
Clarification why the problem happens:
boost::serialization has to ways of implementing the serialize function. As class method or (in your case) the non-intrusive way of defining a function in the boost::serialization namespace.
So the compiler has to somehow decide which implementation to choose. For that reason boost has a 'default' implementation of the boost::serialization::serialize template function.
Signature:
template<class Archive, class T>
inline void serialize(Archive & ar, T & t, const BOOST_PFTO unsigned int file_version)
Within that function there is a call to T::serialize(...). So when you don't want the intusive version you have to override the boost::serialization::serialize function with something more explicit than the default function-template.
Now the problem: In your case the compiler has to decide if it
a) chooses the version where a parameter has to be casted implicit (test_derived& to test_base&)
b) use the generic function without casting (T is test_derived&)
You want the compiler to use variant a) but the compiler prefers b)
Solution:
I don't know a really good solution. I think i would go with a macro which generates implementations of serialize(...) with the explicit type.
If that isn't a possible solution for you, you could also tell the compiler more explicit what to call:
out & *((test_base<int>*)&d);
and wrap it in some helper function (because no one wants to look at such code all the day)
I hope that is a clear description and helps
In case my explanation was not clear, here is an example:
#include <iostream>
class Base
{
public:
virtual ~Base()
{
}
};
class Derived : public Base
{
public:
virtual ~Derived()
{
}
};
void foo(Base& bar)
{
std::cout << "special" << std::endl;
}
template<typename T>
void foo(T& bar)
{
std::cout << "generic" << std::endl;
}
int main()
{
Derived derived;
foo(derived); // => call to generic implementation
foo(*((Base*) &bla)); // => call to special
return 0;
}