I am creating a lua binding in C++11. I want to process each type in a variadic template.
I was thinking I could do something like this, except using Params... represents all of the types inside of it, and not a the next single type inside of it like variadic function parameters do.
template <class T, typename ReturnType, typename... Params>
struct MemberFunctionWrapper <ReturnType (T::*) (Params...)>
{
static int CFunctionWrapper (lua_State* luaState)
{
for(int i = 0; i < sizeof...(Params); i++)
{
//I want to get the next type, not all of the types
CheckLuaValue<Params...>();
//Do other stuff
}
}
};
How would I go about doing this?
You can do this by simply expanding after the function call, into something that can be expanded to.
// put this in your namespace
struct Lunch { template<typename ...T> Lunch(T...) {} };
// and this instead of the for loop
Lunch{ (CheckLuaValue<Params>(), void(), 0)... };
You can do something else with a lambda. You can even have your i incremented
static int CFunctionWrapper (lua_State* luaState)
{
int i = 0;
Lunch{
(CheckLuaValue<Params>(),
[&]{ std::cout << "That was param " << i << std::endl; }(),
++i)...
};
}
Note that the Standard supports putting everything into the lambda. Compiler support until recently (last time I checked) wasn't very good though
static int CFunctionWrapper (lua_State* luaState)
{
int i = 0;
Lunch{([&]{
CheckLuaValue<Params>();
std::cout << "That was param " << i << std::endl;
}(), ++i)...
};
}
Related
I have got an untypical requirement. I'm writing a setup library function, which should be called with only constant values and class names. I made something like this:
template <unsigned index, class layerClass, typename...Args>
void setup_layers() {
//add layer
//recursively call yourself
setup_layers<Args...>();
}
template <unsigned index, class layerClass>
void setup_layers() {
//add layer
}
When I try use my function:
struct MyLayer {};
int main (int argc, char **argv)
{
constexpr unsigned LAYER_NUM = 0;
setup_layers<LAYER_NUM, MyLayer>();
return 0;
}
the compiler reports the error call of overloaded ‘setup_layers<LAYER_NUM, MyLayer>()’ is ambiguous
I'm not sure how can I accomplish my requirement in the other way :(. If I could pass class names as parameters to my function via normal arguments it would be fine, but C++ has no such feature...
EDIT
OK, it seems my "solution" goes nowhere and simply doesn't work.
Because I don't want to delete a question with answers, then maybe I should ask my question differently:
I want users of my library to set a list of layers with indexes (where numbers in those indexes doesn't have to have consecutive numbers). The reason why I wanted to do it using templates is because templates can allow only constant values as parameters. To put it simply: I want to forbid my users from using variables as parameters for indexes.
Here's one option to resolve the ambiguity: You could rename the function doing the actual setup implementation. I've called it setup_impl:
template <unsigned index, class layerClass>
void setup_impl() {
//add layer
std::cout << index << '\n';
}
template <unsigned index, class layerClass, class... Args>
void setup_layers() {
setup_impl<index, layerClass>();
if constexpr (sizeof...(Args) > 0) {
setup_layers<index + 1, Args...>();
}
}
Demo
If index is supposed to be the same every time a Layer class is used, you could make the index a property of the Layer classes.
Example:
template <class layerClass>
void setup_impl() {
std::cout << layerClass::index << '\n';
}
template <class... Args>
void setup_layers() {
(setup_impl<Args>(), ...); // fold expression
}
struct MyLayer1 { static constexpr unsigned index = 11; };
struct MyLayer2 { static constexpr unsigned index = 22; };
struct MyLayer3 { static constexpr unsigned index = 33; };
Demo
There are two errors.
setup_layers<Args...>(); doesn't pass any integral template argument to setup_layers. There is no definition of setup_layers that doesn't have an unsigned value template parameter at the first position, so this call doesn't match anything. Try e.g. setup_layers<index+1, Args...>()>; instead.
The two overloads are ambiguous when there is exactly one type parameter passed.
template <unsigned index, class layerClass, typename...Args> ...
template <unsigned index, class layerClass /*, nothing */> ...
An empty typename ... Args pack is legitimate and there is no reason to prefer an empty parameter pack over nothing, or vice versa. Try removing class layerClass from the second overload (and have it do nothing). template <unsigned index> void setup_layers() {} should do.
You can do it like this:
#include <iostream>
#include <typeinfo>
template <int index, class layerClass>
void setup_layers(int layer) {
//add layer
std::cout << "Adding layer " << layer << ": " << typeid(layerClass).name() << std::endl;
}
template <class layerClass, typename...Args>
void setup_layers(int layer) {
//add layer
//recursively call yourself
if constexpr (sizeof...(Args) > 0) {
setup_layers<0, layerClass>(++layer);
setup_layers<Args...>(layer);
} else {
setup_layers<0, layerClass>(layer);
}
}
struct MyLayer {};
struct OtherLayer {};
int main() {
setup_layers<MyLayer, OtherLayer, MyLayer, OtherLayer>(0);
std::cout << "End" << std::endl;
}
Output:
Adding layer 1: 7MyLayer
Adding layer 2: 10OtherLayer
Adding layer 3: 7MyLayer
Adding layer 3: 10OtherLayer
End
So I have a function where, using C++17, I'm able to apply any method from any object:
#include <functional>
template <typename Object, typename Method, typename ... Args>
void ApplyMethod (Object && object, Method && method, Args && ... args)
{
std::invoke(method, object, args...);
}
What I ask: Is there a way to improve this to require less work for the caller of the function when the method is overloaded.
Example use with overloaded methods:
#include <iostream>
class Foo
{
int bottles;
public:
void Edit ()
{
bottles = 666;
}
void Edit (int number)
{
bottles = number;
}
void Talk () const
{
std::cout << bottles << " bottles of beer of the wall" << std::endl;
}
};
class Bar
{
Foo foo;
void TrickEdit (int number)
{
// Because Foo::Edit is overloaded, we need to do some work:
using Method = void (Foo::*)(int);
Method ptr = &Foo::Edit;
ApplyMethod(foo, ptr, number);
}
void TrickTalk () const
{
// it's a lot neater when the method isn't overloaded:
ApplyMethod(foo, &Foo::Talk);
}
public:
void Trick ()
{
TrickEdit(900);
TrickTalk();
}
};
int main ()
{
Bar().Trick();
return 0;
}
I'm trying to perform the work at the function instead. The problem seems to lie in that &Foo::Edit has two different locations, depending on which Edit we're referring to.
In C++ FAQ - Pointers to member functions by Stroustrup and other reputable authors, I read:
Question: I need something like function-pointers, but with more flexibility and/or thread-safety; is there another way?
Answer: Use a functionoid.
Question: What the heck is a functionoid, and why would I use one?
Answer: Functionoids are functions on steroids. Functionoids are strictly more powerful than functions, and that extra power solves some (not all) of the challenges typically faced when you use function-pointers. [...] Functionoids don’t solve every problem encountered when making flexible software, but they are strictly more powerful than function-pointers and they are worth at least evaluating. In fact you can easily prove that functionoids don’t lose any power over function-pointers, since you can imagine that the old-fashioned approach of function-pointers is equivalent to having a global(!) functionoid object. Since you can always make a global functionoid object, you haven’t lost any ground. QED.
Given that the "power" of programming is basically the reduction of work duplication, and that with a normal function we would avoid the extra work at the call site that I've outlined in my problem, the FAQ answer implies that there should be a solution to this using functionoids. However, for the life of me, I can't see how functionoids would help in this case.
Maybe you can use something like that:
struct A
{
void Do() { std::cout << "Do no parm" << std::endl; }
void Do(int) { std::cout << "Do 1 parm" << std::endl; }
void Do(int,int) { std::cout << "Do 2 parms" << std::endl; }
};
template < typename OBJ_TYPE, typename ... ARGS >
auto Invoke( OBJ_TYPE&& obj, void( std::remove_reference<OBJ_TYPE>::type::* func)(ARGS...), ARGS&& ... args )
{
return std::invoke( func, obj, args... );
}
int main()
{
A a;
Invoke( a, &A::Do);
Invoke( a, &A::Do, 1);
Invoke( a, &A::Do,1,2);
}
The idea is simply to fix the pointer type of the member function pointer to the given arguments in the parameter pack.
If someone has an idea how to automatically determine the return type, so that we also can use overloads with different return types, that would be very funny! I end up in a recursion :-)
If we simply specify the return type, we can use it as follows:
struct A
{
void Do() { std::cout << "Do no parm" << std::endl; }
void Do(int) { std::cout << "Do 1 parm" << std::endl; }
int Do(int,int) { std::cout << "Do 2 parms" << std::endl; return 42;}
};
template < typename RETURN_TYPE, typename OBJ_TYPE, typename ... ARGS >
auto Invoke( OBJ_TYPE&& obj, RETURN_TYPE( std::remove_reference<OBJ_TYPE>::type::* func)(ARGS...), ARGS&& ... args )
{
return std::invoke( func, obj, args... );
}
int main()
{
A a;
Invoke<void>( a, &A::Do);
Invoke<void>( a, &A::Do, 1);
int retval = Invoke<int>( a, &A::Do,1,2);
std::cout << retval << std::endl;
}
You can write a variable template that specifies what Args... should be.
template <typename... Args>
struct Overload {
template<typename R, typename O>
operator R(O::*)(Args...) (R(O::*p)(Args...)) const { return p; }
template<typename R, typename O>
operator R(O::*)(Args...) const (R(O::*p)(Args...) const) const { return p; }
};
template <typename... Args>
Overload overload;
Which is used like
struct A
{
void Do() { std::cout << "Do no parm" << std::endl; }
void Do(int) { std::cout << "Do 1 parm" << std::endl; }
void Do(int,int) { std::cout << "Do 2 parms" << std::endl; }
};
template <typename Object, typename Method, typename ... Args>
void ApplyMethod (Object && object, Method && method, Args && ... args)
{
std::invoke(method, object, args...);
}
int main()
{
A a;
ApplyMethod( a, overload<>(&A::Do));
ApplyMethod( a, overload<int>(&A::Do), 1);
ApplyMethod( a, overload<int, int>(&A::Do),1,2);
}
This is what Qt does for it's modern signals and slots.
I am creating a class that allows me to store lambdas that need to be executed (in order) at a point in the future.
class Promise{
private:
//snip//
std::vector<std::function<void()>> lchain;
public:
//snip//
void then(const std::function<void()> &f){
if (this->resolved) {//If the promise is resolved we just call the newly added function, else we add it to the lchain queue that will be processed later
f();
return;
}
lchain.push_back(f);
}
void launch(){
this->resolved = true;
for (auto &fun: this->lchain)
fun();
}
}
It is obvious that it will only work with lambdas with a signature like [&](){} but some of the tasks need to work with an arbitrary number of parameters of arbitrary types (both, parameters and types are known in advance, when the function is added to the queue).
An example driver program that currently works is
int main(){
Promise* p = new Promise([](){
std::cout << "first" << std::endl;
})->then([](){
std::cout << "second" << std::endl;
});
Promise->launch(); //In my code promise chains are picked up by worker threads that will launch them.
}
An example program I would like to execute:
int main(){
Promise* p = new Promise([](){
return 5;
})->then([](int n){
return n*n;
})->then([](int n){
std::cout << n << std::endl; //Expected output: 25
});
Promise->launch();
}
Things that I am struggling to do:
Storing lambdas of mixed signatures in a std::vector
Making the then() method call f with the arguments associated with f
Making the then() function return the result of f so it can be fed to the next lambda in the chain (preferably binding it before storing the lambda in the vector)
I have been searching in stackoverflow the whole day but the closest I got was this but I would like something that can be done in the then() method to simplify the program code as it would be a pain to bind every single lambda before calling the then() method.
I have something that I think does what you want. I'll start with an example and then introduce the implementation.
int main(){
Promise p([] {
return 5;
});
p.then([](int n) {
return n*n;
}).then([](int n) {
std::cout << n << '\n';
});
p.launch();
struct A { int n; };
struct B { int n; };
struct C { int n; };
Promise q([](A a, int n) {
std::cout << "A " << a.n << ' ' << n << '\n';
return B{2};
});
q.then([](B b) {
std::cout << "B " << b.n << '\n';
return C{3};
}).then([](C c) {
std::cout << "C " << c.n << '\n';
});
q.launch(A{1}, 111);
Promise<B(A, int)> r([](auto a, int n) {
std::cout << "A " << a.n << ' ' << n << '\n';
return B{5};
});
r.then([](auto b) {
std::cout << "B " << b.n << '\n';
return C{6};
}).then([](auto c) {
std::cout << "C " << c.n << '\n';
});
r.launch(A{4}, 222);
}
This outputs:
25
A 1 111
B 2
C 3
A 4 222
B 5
C 6
Some drawbacks:
Calling then after the promise has been resolved doesn't automatically call the function. Things get confusing in that situation and I'm not even sure if it's possible.
You can't call then multiple times on the same promise. You have to build a chain and call then on the result of the previous then.
If any of those drawbacks make this unusable, then you can stop reading this humongous answer.
The first thing we need is a way of getting the signature of a lambda. This is only used for the deduction guide so it isn't strictly necessary for the core concept to work.
template <typename Func>
struct signature : signature<decltype(&Func::operator())> {};
template <typename Func>
struct signature<Func *> : signature<Func> {};
template <typename Func>
struct signature<const Func> : signature<Func> {};
template <typename Ret, typename... Args>
struct signature<Ret(Args...)> {
using type = Ret(Args...);
};
template <typename Class, typename Ret, typename... Args>
struct signature<Ret (Class::*)(Args...)> : signature<Ret(Args...)> {};
template <typename Class, typename Ret, typename... Args>
struct signature<Ret (Class::*)(Args...) const> : signature<Ret(Args...)> {};
template <typename Func>
using signature_t = typename signature<Func>::type;
The next thing we need is a base class. We know the next promise must accept the return type of the current promise as an argument. So we know the argument type of the next promise. However, we don't know what the next promise will return until then is called so we need a polymorphic base to refer to the next promise.
template <typename... Args>
class PromiseBase {
public:
virtual ~PromiseBase() = default;
virtual void launch(Args...) = 0;
};
Now we have the Promise class itself. You can construct a promise with a function. As I alluded to above, a promise stores a pointer to the next promise in the chain. then constructs a promise from the given function and stores a pointer to it. There is only one next pointer so you can only call then once. There's an assertion to make sure this doesn't happen. launch calls the stored function and passes the result to the next promise in the chain (if there is one).
template <typename Func>
class Promise;
template <typename Ret, typename... Args>
class Promise<Ret(Args...)> : public PromiseBase<Args...> {
public:
template <typename Func>
explicit Promise(Func func)
: handler{func} {}
template <typename Func>
auto &then(Func func) {
assert(!next);
if constexpr (std::is_void_v<Ret>) {
using NextSig = std::invoke_result_t<Func>();
auto nextPromise = std::make_unique<Promise<NextSig>>(func);
auto &ret = *nextPromise.get();
next = std::move(nextPromise);
return ret;
} else {
using NextSig = std::invoke_result_t<Func, Ret>(Ret);
auto nextPromise = std::make_unique<Promise<NextSig>>(func);
auto &ret = *nextPromise.get();
next = std::move(nextPromise);
return ret;
}
}
void launch(Args... args) override {
if (next) {
if constexpr (std::is_void_v<Ret>) {
handler(args...);
next->launch();
} else {
next->launch(handler(args...));
}
} else {
handler(args...);
}
}
private:
using NextPromise = std::conditional_t<
std::is_void_v<Ret>,
PromiseBase<>,
PromiseBase<Ret>
>;
std::unique_ptr<NextPromise> next;
std::function<Ret(Args...)> handler;
};
Finally, we have a deduction guide.
template <typename Func>
Promise(Func) -> Promise<signature_t<Func>>;
Here's an online demo.
Is there a way to code a single template function able to run on different members of a given struct ?
A wrong example would look like :
struct Foo
{
int a, b;
}
template <MEMBER x> //which does not exist
cout_member(Foo foo)
{
cout << foo.x << endl;
}
int main()
{
Foo foo;
cout_member<a>(foo);
cout_member<b>(foo);
return 0;
}
I imagined an answer based on a switch, but I then wondered if this switch would be tested on run-time (what I would like to avoid) or on compile-time ?
As long as you want to pick up a data member from a set of data members having the same type, you can use a pointer to data member:
template <int Foo::*M>
void cout_member(Foo foo)
{
std::cout << (foo.*M) << std::endl;
}
And use it as:
cout_member<&Foo::a>(foo);
If you want to indicate also the type, you can do this:
template <typename T, T Foo::*M>
void cout_member(Foo foo)
{
std::cout << (foo.*M) << std::endl;
}
And use it as:
cout_member<int, &Foo::a>(foo);
Just out of curiosity, the second snippet would be even simpler in C++17:
template <auto M>
void cout_member(Foo foo)
{
std::cout << (foo.*M) << std::endl;
}
See it up and running on wandbox;
You can leverage std::mem_fn so you don't even have to care: (untested)
template < typename Fun, typename ... Params >
void print(Fun f, Params && ... p) { std::cout << f(std::forward<Params>(p)...) << "\n"; }
print(std::mem_fn(&Obj::fun), Obj());
Since you're using streams you probably don't care...but this should add little to zero overhead from just writing cout << obj.fun().
Edit: mem_fn works on data members too. Creates a callable that returns a reference to the value that you can then use: int x = mem_fn(&pair<int,char>::first)(my_pair);
I would like to have a general function 'request' which could accept a tuple of any number of arguments. I want the 'request' function to dispatch the call to a number of other functions, depending on the number of arguments (of course the interface of the functions must match).
I wrote this code, but it only works if I call function of one type inside the 'request'. As soon as I uncomment the dispatching mechanism (else -> dispatch to fun5) everything stops compiling.
The problem is that the body of function 'request', created for the case of dispatching to function with two parameters, must compile, and then there is a function with 5 arguments inside it, to which the tuple of 2 arguments cannot be applied. And vice versa. Classic problem with templates. I know that I could somehow apply SFINAE concept to this problem, but I somehow don't know how (I am not as strong in MPL programming).
#include <iostream>
#include <experimental/tuple>
enum class type { v2, v5 };
void fun2(int i1, int i2)
{
std::cout << "fun2 called, i1 = " << i1 << ", i2 = " << i2 << std::endl;
}
void fun5(bool b1, float f1, int i, char c, bool b2)
{
std::cout << "fun5 called with: " << std::boolalpha << b1 << ", " << f1 << ", " << i << ", " << c << ", " << b2 << std::endl;
}
template <typename F, typename... T>
void dispatch(F f, T... args)
{
std::experimental::apply(f, args...);
}
template <typename... T>
void request(type t, T... args)
{
if (t == type::v2)
dispatch(fun2, args...);
// else
// dispatch(fun5, args...);
}
int main()
{
auto v2 = std::make_tuple(1,1);
request(type::v2, v2);
// auto v5 = std::make_tuple(true, 1.5f, 3, 'c', false);
// request(type::v5, v5);
}
How can I make this work? What kind of dispatching mechanism I need here to make this work?
Instead of using an enumeration to select what to do, I suggest you use tags and tag structures instead. Then you can simply select the right dispatch function using simple function overloading.
Perhaps something like
namespace type
{
struct v2_tag {};
struct v5_tag {};
v2_tag v2;
v5_tag v5;
}
template<typename... T>
void request(type::v2_tag, T... args)
{
dispatch(fun2, args...);
}
template<typename... T>
void request(type::v5_tag, T... args)
{
dispatch(fun5, args...);
}
The rest of the code stays the same.
An alternative to tag dispatch (which I highly recommend as per #Some programmer dude) would be to create your own function object that accepts a type as a non-type template argument so that we can take advantage of constexpr if:
template<type t>
struct request
{
template<class... T>
void operator()(T... args) const
{
if constexpr(t == type::v2)
dispatch(fun2, args...);
else
dispatch(fun5, args...);
}
};
The downside is that you have to construct one to make your call:
auto v2 = std::make_tuple(1, 1);
request<type::v2>()(v2);
auto v5 = std::make_tuple(true, 1.5f, 3, 'c', false);
request<type::v5>()(v5);
Demo
A variation on this approach is to instead have a static apply function in your request class like so:
template<type t>
struct request{
template<class... T>
static void apply(T... args){/*..*/}
}
And then a call to it would look like this instead (no funky empty braces):
request<type::v2>::apply(v2);
Demo2