How to invoke the template function in a loop manner? - c++

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.

Related

How to define a vector of functions that accepts different parameter types in c++?

I am doing a challenge for myself and writing a program in C++ without using classes and class related machinery. Additional conditions are I can use everything from stl and have full type safety, meaning no raw pointers or casting from one type to another. I am now in a situation where I'm not sure how to proceed with the constraints I have put on myself.
Problem: I want to create a std::vector of functions, but each of those functions might take a different data type, and operate on that type only. Example:
struct DataAndFunction {
AnyDataType data;
std::function<void(AnyDataType&)> functionOperatingWithData;
};
...
std::vector<DataAndFunction> listOfFunctions;
...
for(auto& dataAndFunc : listOfFunctions) {
dataAndFunc.functionOperatingWithData(dataAndFunc.data);
}
then there either would be different kind of AnyDataType and accompanying functions.
I know it could be solved in a couple of ways:
with classes using polymorphism, where
std::vector< DataAndFunction > listOfFunctions;
would just take a base class as a template parameter, and would have virtual method, that would be implemented by child classes, each with their own private data members, but the point of my challenge is to not use this pattern.
I could pass void* as data and function signature, and inside each function I would cast the data to the appropriate type, but I want to use type safety and only smart pointers
I could also make DataAndFunction struct a generic by adding template parameter, but then how do I make a vector that could be filled with not just with of DataAndFunction<int> for example, but any template parameter?
And how would this problem be solved in a more functional style? How would a functional solution look in C++ that would operate on a list of functions each taking a different type of argument? Without using inheritance of course.
Or am I just asking how to emulate a virtual table?
It seems you only need std::function<void()>:
DataAndFunction<int> dint;
DataAndFunction<char> dchar;
std::vector<std::function<void()>> funcs{
[&](){ dint.f(dint.data); },
[&](){ dchar.f(dchar.data); },
[](){ std::cout << "Hello world\n"; }
};
for (auto& f : funcs) {
f();
}
How you know, C++ is a strong typed language. That means you can't have a generic variable like others languages do like Python.
In C, the solution is to use a point to void (void*), but it is hard to manage and error-prone.
C++17 comes with 2 elegant solutions these you can use:
std::any and
std::variant.
This is one way you could store a vector of functions that take different types as parameters, it also accepts a varying amount of parameters. It uses std::any, std::pair, and std::tuple to contain the function and its parameter(s). std::any is much safer than a void * however there is more memory overhead as std::any stores quite a bit of data.
the program simply outputs : "Hello World!"
#include <any>
#include <tuple>
#include <string>
#include <vector>
#include <utility>
#include <iostream>
#include <functional>
std::vector<std::pair<std::function<void(const std::any&)>, std::any>> funcList;
template <typename F, typename...T>
std::size_t insertAnyFunc(const F &func, const T&...params) {
auto t = std::make_tuple<const T&...>(params...);
funcList.push_back({
[f = func](const std::any &a) {
if constexpr (sizeof...(T) == 0)
f();
else
std::apply(f, std::any_cast<const std::tuple<T...> &>(a));
}, std::make_any<std::tuple<T...>>(t)
});
return funcList.size();
}
void execAnyFunc(const std::size_t &ID) {
if (ID < funcList.size())
funcList.at(ID).first(funcList.at(ID).second);
}
int main (void) {
insertAnyFunc([](const std::string &s){ std::cout << s; }, std::string("Hello World!\n"));
execAnyFunc(0);
return 0;
}

Static duck typing in C++

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());
}

map of pointers to functions of different return types and signatures

I am looking for a way to call different functions by a string input.
I have a map that ties each unique string to a function pointer and a lookup function to search the map and return a pointer if found.
Now the trick is, I need a way to store and return pointers to functions with at least different return types, if possible, also with different signatures.
The usage would be:
Get a string input from a network socket ->
find and execute the found function -> shove the result straight back into the socket to be serialized and sent, not caring what actually happened.
Is this doable? If not, how would one approach this task?
That can be done with a bit of boilerplate code in different ways. If the number of signatures is small enough you can hold multiple vectors of function pointers (one per function type) and then a map that maps the function name with a type identifier (used to select the vector) and the position within the vector.
The second option would be to store a boost::variant (again, if the set of signatures is small). You would need to provide a visitor object that evaluates the function (for each function type stored) and yields the result. The type is managed by the boost::variant type so there would be no need for the type tag to be stored in the map.
You can also use full type erasure and store in the map a tag determining the type of function to be called and a boost::any object storing the function pointer. You can use the type information to retrieve the pointer and execute the function, but you will have to manually handle the switch based on function type.
The simplest approach, on the other hand, is to write adapters that have a fixed interface. Then just store the pointers to the adapters in the map.
While you can't store different function pointers, you can store objects which contain those functions.
#include <iostream>
#include <cmath>
#include <map>
#include <string>
using namespace std;
class Functor{
public:
template<class T>
void operator()(T data){}
};
template<class T>
class BaseFunctor : public Functor{
public:
virtual void CallFunction(T data){ }
};
class FunctionPointer1 : public BaseFunctor<void *>{
public:
void doFunction1(){
cout << "Do Function 1"<<endl;
}
template<class T>
void CallFunction(T data){ doFunction1(); }
template<class T>
void operator()(T data){ this->CallFunction(data); }
};
class FunctionPointer2 : public BaseFunctor<int>{
public:
void doFunction2(int variable){ cout << "Do function 2 with integer variable" << variable <<endl; }
template<class T>
void CallFunction(T data) { doFunction2(data);}
template<class T>
void operator()(T data){ this->CallFunction(data); }
};
class FunctionPerformer{
private:
map<string,Functor> functions;
public:
FunctionPerformer(){
//init your map.
FunctionPointer1 function1;
FunctionPointer2 function2;
//-- follows
functions["Function1"] = function1;
functions["Functions2"] = function2;
//-- follows
}
Functor getFunctionFromString(string str){
return functions[str]
}
};
int main(int argc, char *argv[])
{
map<string,Functor> functions;
FunctionPerformer performer;
Functor func1, func2; // to hold return values from perfomer()
FunctionPointer1 *fn1; // to casting and execute the functions
FunctionPointer2 *fn2; // to casting and execute the functions
func1 = performer.getFunctionFromString("Function1");//get data
func2 = performer.getFunctionFromString("Function2");
//following two lines to cast the object and run the methods
fn1 = reinterpret_cast<FunctionPointer1 *>(&func1);
(*fn1)(NULL);
//following two lines to cast the object and run the methods
fn2 = reinterpret_cast<FunctionPointer2 *>(&func2);
(*fn2)(10);
system("Pause");
return 0;
}
I think the edited part makes it clearer?
This code can be optimized a little. Play around with it.
This is doable in C++11 with Variadic Templates. Check my answer at https://stackoverflow.com/a/33837343/1496826
No, it's really not doable, you need a real interpreted language if you want to do something like this. As soon as the signature is not constant then you need something a lot more involved.
How about making all those functions have the same signature? You could make all return types implement an interface, or use a collection, class, union or struct. Same for the arguments.
Can't you use specialization and templates to work around the issue?
template <class T>
T FooBar(void * params);
template<> int FooBar<int>( void * params );
template<> char FooBar<char>( void * params );
Instead of storing the function pointers themselves, which are too different from one another to be accommodated into the same data structure, you can store adaptors that take care of bridging the mismatch. This is a form of type-erasure. An example:
// Imaginary important resources
blaz_type get_blaz();
qux_type get_qux();
// The functions we'd like to put in our map
int foo(blaz_type);
std::string bar(qux_type);
using context_type = std::tuple<blaz_type, qux_type>;
using callback_type = std::function<void(context_type, socket_type&)>;
using std::get;
std::map<std::string, callback_type> callbacks = {
{
"foo"
, [](context_type context, socket_type& out)
{ marshall(out, foo(get<0>(std::move(context)))); }
}
, {
"bar"
, [](context_type context, socket_type& out)
{ marshall(out, bar(get<1>(std::move(context)))); }
}
};
In this example the adaptors are not stateful so you can actually use void (*)(context_type, socket_type&) as the callback_type.
Do note that this kind of design is a bit brittle in that the context_type needs to know about every kind of parameter a stored callback might ever need. If at some later point you need to store a callback which needs a new kind of parameter, you need to modify context_type -- if you improve the above design not to use magic numbers like 0 and 1 as parameters to std::get you could save yourself some pains (especially in the reverse situation of removing types from context_type). This is not an issue if all callbacks take the same parameters, in which case you can dispense yourself with the context_type altogether and pass those parameters to the callbacks directly.
Demonstration on LWS.

Storing map's first element to a vector in the most generic form. Best solution

My goal is to store all the keys of a map (first item) to a vector and I'm doing the following.
template < class vecDet>
class storeInto
{
public:
storeInto(vecDet& source) : VectorInfo(source) { }
~storeInto();
template <class pairdet>
void operator()(pairdet& pairinfo)
{
VectorInfo.push_back(pairinfo.first);
}
private:
vecDet& VectorInfo;
};
template<class mapDet, class vecDet>
void storeMapToVector(const mapDet& mapContA, vecDet& vecContA)
{
for_each(mapContA.begin(), mapContA.end() , storeInto<vecDet>(vecContA));
}
Finally, from my main program, I'm calling the storeMapToVector() as follows
storeMapToVector<mapinfo,vector<char> >(mapContents, vecContents);
where mapinfo is declared as follows
typedef map<char,int> mapinfo;
Is there a better way to do this? Is there anything wrong with this?
Your code looks like it would work at first glance. However, there's a much simpler way to do this:
I haven't evaluated your code, but there is certainly a much easier way to do what you want built into most STL implementations:
vecContents.resize(mapContents.size());
std::transform(mapContents.begin(), mapContents.end(), vecContents.begin(),
select1st<pair<const char, int> >());
Alternatively:
vecContents.resize(mapContents.size());
std::transform(mapContents.begin(), mapContents.end(), vecContents.begin(),
select1st<mapinfo::value_type>());
There is 1 wrinkle though - select1st is a SGI extension. It's in almost every STL implementation but where varies. For GNU, you have to do:
#include <ext/functional>
using __gnu_cxx::select1st; // or just using namespace __gnu_cxx;
See this answer for using it in Visual Studio.
The code seems fine. Some nitpicks though:
~storeInto();
What do you need the destructor for? The functor could just live without it.
storeMapToVector<mapinfo,vector<char> >(mapContents, vecContents);
The template argument list seems unnecessary here, it could just be
storeMapToVector(mapContents, vecContents);
The template parameters would be inferred in this context.

Specify an inline callback function as an argument

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.