Let me first explain what I'm trying to achieve using some pseudo-code (JavaScript).
// Declare our function that takes a callback as as an argument, and calls the callback with true.
B(func) { func(true); }
// Call the function
B(function(bool success) { /* code that uses success */ });
I hope this says it all. If not, please comment on my question so I can write a little more to clarify my issue.
What I want is to have code like this in C++.
I have tried to use lambda functions, but I was unable to specify a parameter type for those.
If your compiler is a fairly recent release (such as Visual Studio 2010 or GCC 4.5), you can use some new features from the new C++ standard, which is currently in ratification and should be published soon.
I don't know what you need to do to enable this in Visual Studio, but it should be well-documented either on MSDN or internal help.
For GCC 4.5, just add the -std=c++0x option to enable the new features.
One of these features is the Lambda syntax:
template <typename F>
void func_with_callback(F f) {
f(true);
}
int main() {
func_with_callback( [](bool t){ if(t) cout << "lambda called" << endl; } );
}
If you don't have access to a modern compiler, you can use techniques such as functors and libraries like boost::lambda, which can perform similarly.
EDIT: Upon reading your question again, it looks like you might be looking for anonymous functions in C++. If that's what you want, unfortunately the language does not support that feature. C++ requires you be a bit more verbose with those sorts of things at present time. If you need more than what boost::lamda is already providing you then you should probably separate it out as a normal function anyway.
In C and C++ this is accomplished using function pointers or functors and templates (C++ only).
For example (using the C++ way (functors))
//Define a functor. A functor is nothing but a class which overloads
//operator(). Inheriting from std::binary_function allows your functor
//to operate cleanly with STL algorithms.
struct MyFunctor : public std::binary_function<int, int, bool>
{
bool operator()(int a, int b) {
return a < b;
};
};
//Define a template which takes a functor type. Your functor should be
//should be passed by value into the target function, and a functor should
//not have internal state, making this copy cheap.
template <typename Func_T>
void MyFunctionUsingACallback(Func_T functor)
{
if (functor(a, b))
//Do something
else
//Do something else
}
//Example usage.
int main()
{
MyFunctionUsingACallback(MyFunctor());
}
Using the C way (function pointers):
//Create a typedef for a function pointer type taking a pair of ints and
//returning a boolean value.
typedef bool (*Functor_T)(int, int);
//An example callback function.
bool MyFunctor(int a, int b)
{
return a < b;
}
//Note that you use the typedef'd function here.
void MyFunctionUsingACallback(Functor_T functor)
{
if (functor(a, b))
//Do something
else
//Do something else
}
//Example usage.
int main()
{
MyFunctionUsingACallback(MyFunctor);
}
Note that you should prefer the C++ way because it will allow the compiler to
make more intelligent decisions with regards to inlining, unless for some reason
you are limited to the C subset.
Related
This question is mostly about the design approach, and I would like to know how to solve such kind of problems in the modern C++ language.
I have a library function that defined like (this is a real code from the compiler):
template <info::device param>
typename info::param_traits<info::device, param>::return_type
get_info() const;
In order to call this function, I could write something like:
some_device.get_info<cl::sycl::info::device::device_type>()
where cl::sycl::info::device::device_type is an actual parameter.
There a long list of supported parameters and I would like to have a collection of result values (results of different function calls).
At this moment, I could do something like:
some_device.get_info<cl::sycl::info::device::param1>()
some_device.get_info<cl::sycl::info::device::param2>()
...
some_device.get_info<cl::sycl::info::device::paramN>()
but because this is terrible, I am looking for a better solution in C++ 11/14.
With fold expressions no explicit loop (or recursion) is needed. For example:
#include <iostream>
#include <string>
template <typename T>
void foo(){ std::cout << T{}; } // just an example
template <typename...Args>
void bar() {
(foo<Args>(),...); // call foo for each type in Args
}
int main() {
bar<int,double,std::string>();
}
To have a "collection" of supported types you could use using collection = std::tuple<int,double,std::string>;.
For all this kind of code I use Boost.Hana iterating on tuples with a boost::hana::for_each, either from user point-of-view but also for SYCL internal implementation.
C++ has some sort of duck typing for types given by template parameters. We have no idea what type DUCK1 and DUCK2 will be, but as long as they can quack(), it will compile and run:
template <class DUCK1, class DUCK2>
void let_them_quack(DUCK1* donald, DUCK2* daisy){
donald->quack();
daisy->quack();
}
But it's a bit inconvenient to write. When I do absolutely not care what actual types DUCK1 and DUCK2 are but rather want to fully use the idea of duck typing, then I would like to have something sligthly different than above:
I'd like to omit writing a template parameter list that is repetitive and mostly meaningless (Just imagine what would happen if there are 7 ducks...)
I'd like to make it a bit more explicit that the types are never used and that it's only the interface that matters.
I'd like to have sort of an interface annotation/check. Make somehow clear what interface is expected behind the type. (That's, however, a bit in contrast of duck typing.)
Does C++ offer any features to achieve one or more of the 3 ideas?
(I know that virtual inheritance is the method of choice in most cases to implement such patterns, but the question here is specifically about the case of static polymorphism.)
Concerning questions 1 and 2: since C++14 you can omit explicit template <typename ... boilerplate and use auto, but only in lambdas:
auto let_them_quack = [] (auto & donald, auto & daisy){
donald.quack();
daisy.quack();
};
(yes, I prefer references to pointers). GCC allows to do so in usual functions as an extension.
For the question 3, what you are talking about are called concepts. They existed in C++ for a long time, but only as a documentational term. Now the Concepts TS is in progress, allowing you to write something like
template<typename T>
concept bool Quackable = requires(T a) {
a.quack();
};
void let_them_quack (Quackable & donald, Quackable & daisy);
Note that it is not yet C++, only a technical specification in progress. GCC 6.1 already seems to support it, though. Implementations of concepts and constraints using current C++ are possible; you can find one in boost.
I'd like to omit writing a template parameter list that is repetitive
and mostly meaningless (Just imagine what would happen if there are 7
ducks...)
For that you could use variadic templates and do something like the following:
template<typename DUCK>
void let_them_quack(DUCK &&d) {
d.quack();
}
template<typename DUCK, typename... Args>
void let_them_quack(DUCK &&d, Args&& ...args) {
d.quack();
let_them_quack(std::forward<Args>(args)...);
}
Live Demo
#2 and #3 are sort of taken care of by the fact that the code will not compile, and throw a compilation error, if the given classes don't implement the interface. You could also make this formal:
class duck {
public:
virtual void quack()=0;
};
Then declare the parameters to the function as taking a pointer to a duck. Your classes will have to inherit from this class, making the requirements for let_them_quack() crystal clear.
As far as #1 goes, variadic templates can take care of this.
void let_them_quack()
{
}
template <typename ...Args>
void let_them_quack(duck* first_duck, Args && ...args) {
first_duck->quack();
let_them_quack(std::forward<Args>(args)...);
}
You will be able to make it look preetier with concept (not yet in standard - but very close):
http://melpon.org/wandbox/permlink/Vjy2U6BPbsTuSK3u
#include <iostream>
template<typename T>concept bool ItQuacks(){
return requires (T a) {
{ a.quack() } -> void;
};
}
void let_them_quack2(ItQuacks* donald, ItQuacks* daisy){
donald->quack();
daisy->quack();
}
struct DisneyDuck {
void quack(){ std::cout << "Quack!";}
};
struct RegularDuck {
void quack(){ std::cout << "Quack2!";}
};
struct Wolf {
void woof(){ std::cout << "Woof!";}
};
int main() {
DisneyDuck q1, q2;
let_them_quack2(&q1, &q2);
RegularDuck q3, q4;
let_them_quack2(&q3, &q4);
//Wolf w1, w2;
//let_them_quack2(&w1, &w2); // ERROR: constraints not satisfied
}
output:
Quack!Quack!Quack2!Quack2!
As you can see, you will be able to: omit writing a template parameter list, ItQuacks is quite explicit so types are never used and that it's only the interface that matters takes place. This I'd like to have sort of an interface annotation/check. also takes place, concept use will also give you meaningfull error message.
We only need to write one version of the function:
#include <utility>
template<typename... Quackers>
void let_them_quack(Quackers&& ...quackers) {
using expand = int[];
void(expand { 0, (std::forward<Quackers>(quackers).quack(), 0)... });
}
struct Duck {
void quack() {}
};
int main()
{
Duck a, b, c;
let_them_quack(a, b, c, Duck());
}
I am working on some c Apis and I always have to check some variables are initialized and then clear/destroy/free them using special functions. such as allocation :
ogg_stream_state os;
ogg_stream_init(&os,ogg_page_serialno(&og));
and destroying:
ogg_stream_clear(&os);
I want to call the cleaner function automatically and not explicitly.
Using C++ Templates you can do it easily:
template<typename ARG, typename RET>
class Destroyer
{
public:
typedef RET (*DestoyerFn)(ARG*);
Destroyer(DestoyerFn destroyer_fn, ARG* object_ptr) { objectPointer = object_ptr; destroyerFn = destroyer_fn;}
~Destroyer()
{
if(destroyerFn && objectPointer)
destroyerFn(objectPointer);
}
private:
DestoyerFn destroyerFn;
ARG* objectPointer;
};
ARG is the argument of your cleaner function, and RET is the return type of that (RET needed to avoid compiler warning.)
example call:
Destroyer<ogg_stream_state, int> des_ogg_stream(ogg_stream_clear, &os);
now every where you like, just return from your function, it will call your cleaner function.
In a real-world scenario you most likely want some kind of custom wrapper around the C functions, to encapsulate them and to dodge C like behavior and oddities such as calling convention.
In the real world, I don't believe you can treat any C code as "a generic C API" and design some template class which can handle all possible C APIs. There are far too many things to consider to make such a generic class feasible.
For example, given the following random C code:
//cfile.c
static int* something;
void cfunction_init (void)
{
printf("C function init\n");
something = (int*) malloc(sizeof(*something));
}
void cfunction_cleanup (void)
{
printf("C function cleanup\n");
free(something);
}
You can make a wrapper class like this:
class wrapper
{
public:
wrapper() { cfunction_init(); }
~wrapper() { cfunction_cleanup(); }
};
Then simply declare a wrapper class variable at the appropriate scope:
#include <iostream>
int main()
{
wrapper w;
std::cout << "C++ program executing" << std::endl;
return 0;
}
Program output:
C function init
C++ program executing
C function cleanup
I'd consider wrapping ogg_stream_state with a shared_ptr with custom destructor.
class OggStreamState {
public:
shared_ptr<ogg_stream_state> state;
OggStreamState() :
state(new ogg_stream_state, &ogg_stream_clear)
{}
};
Your code would now look like this:
OggStreamState os;
ogg_stream_init(os.state.get(),ogg_page_serialno(&og));
Which is a little ugly, but this technique gives a logical place to start moving to an object oriented interface rather than a C function based one.
For example you could then move ogg_stream_init into OggStreamState so that it would become
OggStreamState os;
os.init(ogg_page_seialno(&og));
Take it one step further and repeat for the ogg_page, and you'd get
OggPage og = ...;
OggStreamState os;
os.stream_init(og.serialno());
You could even pull the init all the way into the constructor
OggStreamState os(og.serialno());
or at the extreme...
OggStreamState os(og);
Another advantage of this over a pure sentry RAII (like the solution from Lundin) is that you can pass the OggStreamState in and out of functions with out trouble. The compiler will determine when your last reference is destroyed and call the clear function for you. i.e. you can safely have a
OggStreamState oss = function_that_returns_a_stream_state(...);
Of course this technique does introduce other overheads, but usually they are minimal - also it does blur the ownership of the ogg stream slightly, which many or may not be a good thing...
I want to write a function that calls several sub functions and return the result of these sub functions.
sub functions:
template<class A> A sub1(A a)
template<class B> B sub2(B b, int i)
template<class C> C sub3(C c, string p)
THE function will call these accordingly in the switch statement.
Sorry I only have pseudo code since I am confused with the issue and not start to write the code.
mf(string s)
{
int k;
k = process(s)
string
switch (k){
case 0:
return sub1(k);
case 1:
return sub2(s, k);
case 2:
return sub3(k, s);
default:
break;
}
}
How can I define mf above since there is no return type for it now? using template again?
By the way, my c++ compiler does support c++ 11 standard which I am not so familiar with.
C++ is basically a static-typed language, which means all types of expressions are decided at compile time rather than at run time.
Using dynamic-typing in a static-typed language is possible, but not recommended for widely use. Because doing so you're giving up almost all the polymorphism features provided by the language. You'll have to check types manually, or implement your own dynamic-type-based polymorphism.
If the data returned is not too complex, tagged structure is usually a good idea:
struct Value
{
enum {INT, FLOAT, PTR} type;
union
{
int int_data;
float float_data;
void *ptr_data;
};
};
For more complex data types with a lot of operations needed to support, you should consider using abstract interfaces and inheritance.
If you considered the problem seriously and believe that none of those methods above applies to your problem, and that dynamic typing is the best way, here are some options:
boost::any -- A unique container for all types. Need to test for types and convert them manually before use.
boost::variant -- A union-like container which supports unary polymorphic operations via boost::static_visitor.
Some programming frameworks have their own support for dynamic-typing. One example is QVariant in Qt. If you are in such a framework, it's usually recommended to use them instead of something else from another library.
If you need a function that returns the value of its sub function you need the same return type for all of them.
Here a small meaningless example:
double calculatedPositive(double value)
{
// Do stuff
}
double calculatedNegative(double value)
{
// Do stuff
}
double functionA(double value)
{
if(value > 0)
return calculatePositive(value);
else
return calculateNegative(value);
}
P.-S. We could provide you with a better answer if you'd say what you are trying to achieve ;)
I'm trying to write an event system for my game. The callbacks that my event manager will store can be both plain functions as well as functors. I also need to be able to compare functions/functors so I know which one I need to disconnect from the event manager.
• Initially I tried using boost::function; it handles functions and functors perfectly well, except it has no operator==, so I can't remove callbacks if I want to.
class EventManager
{
typedef boost::function<void (boost::weak_ptr<Event>)> Callback;
std::map<Event::Type, std::vector<Callback>> eventHandlerMap_;
};
• I also tried using boost::signal, but that also gives me a compilation problem related to operator==:
binary '==' : no operator found which takes a left-hand operand of type 'const Functor' (or there is no acceptable conversion)
void test(int c) {
std::cout << "test(" << c << ")";
}
struct Functor
{
void operator()(int g) {
std::cout << "Functor::operator(" << g << ")";
}
};
int main()
{
boost::signal<void (int)> sig;
Functor f;
sig.connect(test);
sig.connect(f);
sig(7);
sig.disconnect(f); // Error
}
Any other suggestions about how I might implement this? Or maybe how I can make either boost:: function or boost::signal work? (I'd rather use boost:: function though, since I've heard signal is rather slow for small collections of items.)
Edit: This is the interface of that I'd like EventManager to have.
class EventManager
{
public:
void addEventHandler(Event::Type evType, Callback func);
void removeEventHandler(Event::Type evType, Callback func);
void queueEvent(boost::shared_ptr<Event> ev);
void dispatchNextEvent();
};
You'll find that most generic function wrappers do not support function equality.
Why is this? Well, just look at your functor there:
struct Functor
{
void operator()(int g) {
std::cout << "Functor::operator(" << g << ")";
}
};
This Functor has no operator==, and therefore cannot be compared for equality. So when you pass it to boost::signal by value, a new instance is created; this will compare false for pointer-equality, and has no operator to test for value-equality.
Most functors don't, in fact, have value-equality predicates. It's not useful very much. The usual way to deal with this is to have a handle to the callback instead; boost::signals does this with its connection object. For example, take a look at this example from the documentation:
boost::signals::connection c = sig.connect(HelloWorld());
if (c.connected()) {
// c is still connected to the signal
sig(); // Prints "Hello, World!"
}
c.disconnect(); // Disconnect the HelloWorld object
assert(!c.connected()); c isn't connected any more
sig(); // Does nothing: there are no connected slots
With this, HelloWorld doesn't need to have an operator==, as you're referring directly to the signal registration.
Have you ever tried libsigc and libsigc++? I started using them in linux and fell in love with them. I now use them in my Windows applications as well. I believe it is more extensible and flexible than boost. It is also a breeze to implement.
I highly recommend you consider Don Clugston's "Member Function Pointers and the Fastest Possible C++ Delegates". You can find the article and download the code from here:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
Among many other benefits, his delegates provide comparison operators (==, !=, <) out of the box. I'm currently using them for a realtime system and find them excellent in every way. I do seem to recall we had to make a minor modification to fix a compiler portability issue; but, that experience will vary based on platform etc.
Also, the article is several years old so you may want to google around for updated code/discussion regarding this delegate implementation if you run into any problems.
No matter, I found the solution. A little template magic and things become simple(r):
template<typename F>
void EventManager::removeEventHandler(Event::Type evType, F func)
{
auto compare = [func](const Callback& other) -> bool {
F const* f = other.target<F>();
if (f == nullptr) return false;
return *f == func;
};
std::vector<Callback>& callbacks = ...;
auto pend = std::remove_if(callbacks.begin(), callbacks.end(), compare);
callbacks.erase(pend, callbacks.end());
}
template<typename R, typename F, typename L>
void EventManager::removeEventHandler(
Event::Type evType, const boost::_bi::bind_t<R, F, L>& func)
{
auto compare = [&func](const Callback& other) -> bool {
auto const* f = other.target<boost::_bi::bind_t<R, F, L>>();
if (f == nullptr) return false;
return func.compare(*f);
};
std::vector<Callback>& callbacks = ...;
auto pend = std::remove_if(callbacks.begin(), callbacks.end(), compare);
callbacks.erase(pend, callbacks.end());
}
I need to handle Boost.Bind objects separately because operator== doesn't actually do comparison for Bind objects, but produce a new functor that compares the result of the other two (read more). To compare Boost.Bind you have to use the member function compare().
The type boost::_bi::bind_t seems to be an internal type of Boost (I guess that's what the underscore in namespace '_bi' means), however it should be safe to use it as all overloads of boost::function_equal also use this type (reference).
This code will work for all types of functors as long as there is an operator== defined that does comparison, or if you're using Boost.Bind. I had a superficial look into std::bind (C++0x), but that doesn't seem to be comparable, so it won't work with the code I posted above.