How to generate a std::get like function for my class? - c++

For example, I have a class
struct A {int a; bool b;};
And I want to generate a template function to get its elements (like the std::get to get a tuple element)
template<unsigned i, class T>
auto Get(T& t);
template<>
int& Get<0, A>(A& a)
{
return a.a;
}
template<>
bool& Get<1, A>(A& a)
{
return a.b;
}
int main()
{
A a;
Get<0>(a) = 10;
Get<1>(a) = true;
return 0;
}
The above code doesn't work. The challenge is that I don't know the returned type of Get for arbitrary class. Any way to implement it? Thanks.

Assuming you wouldn't mind making this in a "manual manner" you can do this really simply.
#include <tuple>
struct A {
int a; bool b;
};
template<size_t N>
auto get(A& a) -> decltype(std::get<N>(std::tie(a.a, a.b))) {
return std::get<N>(std::tie(a.a, a.b));
}
#include <iostream>
int main() {
A a;
get<0>(a) = 10;
get<1>(a) = true;
std::cout << a.a << '\n' << a.b;
}
Output:
10
1

Related

How to write a void function for different Structs/Containers with a template?

For instance I have a function
void func(my_cont &C){
C.membA = 1;
C.membB = 2;
dosomething_with(C);
}
Also what to do in the function, if I have a Struct that does not have a member B?
This is a way to statically check for the existence of a membB member inside the template function.
template<typename T>
void func(T& C)
{
C.membA = 1;
if constexpr (requires() { C.membB; })
{
C.membB = 2;
}
}
int main()
{
struct A
{
int membA;
};
struct B
{
int membA;
int membB;
};
A a;
func(a);
B b;
func(b);
}
Another way to get functionality that differs per type:
Using template specialization, as OP requested.
struct A
{
int membA;
};
struct B
{
int membA;
int membB;
};
template<typename T> void func(T&);
template<> void func<A>(A& a) {
a.membA = 1;
}
template<> void func<B>(B& b) {
b.membA = 1;
b.membB = 2;
}
int main()
{
A a;
func(a);
B b;
func(b);
}

Is there a way to create an array of combined functions compile-time in c++?

I'm working on an NES emulator in c++ and figured that the most efficient way to run opcodes would be to call a function pointer in an array of functions that do exactly what the opcode does.
The problem is that each opcode has a specific operation and memory address. While searching for a solution, I stumbled upon lambda expressions. This is definitely good enough for a NES emulator on modern hardware. However, I can't find a solution such that each function in the array contains the machine code for both the operation and the addressing without defining 256 separate functions.
This is along what I had in mind for a similar function that combines f and g:
int addone(int x) {
return x + 1;
}
int multtwo(int x) {
return 2 * x;
}
something combine(function<int(int)> f, function <int(int)> g) {
/* code here */
}
/*
combine(addone, multtwo) creates a function h that has the same machine code as
int h(x) {
return 2 * x + 1;
}
*/
Any ideas? If I had to take a guess, it would have something to do with templates. Thanks!
I'd say that when you want to write generics for functions that it's kind of a "design pattern" to switch to functors: Compilers are desigined to handle types easily, but handling function pointers for stuff you want to mis-match and keep optimised at compile-time gets ugly!
So we either write our functions as functors, or we wrap them as functors:
struct A
{
static constexpr int Func (int x)
{
return -3*x + 1;
}
};
struct B
{
static constexpr int Func (int x)
{
return -2*x - 5;
}
};
// etc...
If we have nice symmetry in how we'll use them, then we can manage them systematically. Eg. if we always want to combine them like f(g(h(...y(z())...))), then we can solve as follows:
template <class T, class ... Ts>
struct Combine
{
static constexpr int Get ()
{
int x = Combine<Ts...>::Get();
return T::Func(x);
}
};
template <class T>
struct Combine <T> // The base case: the last function in the list
{
static constexpr int Get ()
{
return T::Func();
}
};
demo
Or if we're in no such luck, we'll have to resort to more old-fashioned inputs like you suggested:
template <class Funcs, class Data>
constexpr int Combine (const Data & d)
{
Funcs F;
// Some use without much symmetry:
return F.f(F.g(d)) - F.h(d);
}
int main ()
{
struct FuncArgs
{
A f;
B g;
C h;
};
return Combine<FuncArgs>(5);
}
demo
Note that in the second example I've changed from static methods to non-static. This doesn't really matter - the compiler should optimise these fully regardless, but I think in this case it makes the syntax slightly nicer (and shows an alternative style).
You can do something like this, using a lambda to capture the two functions and to assign a function to a variable:
#include <functional>
#include <iostream>
int addone(int x){
return x + 1;
}
int multtwo(int x){
return x * 2;
}
std::function<int(int)> combine(std::function<int(int)> f, std::function<int(int)> g){
auto tmp = [&](int x){ return f(g(x)); };
return std::function<int(int)>(tmp);
}
int main(){
auto h = combine(std::function<int(int)>(addone), std::function<int(int)>(multtwo)); // (2 * x) + 1
std::cout << h(10); // Prints 21
}
If you want it to generally combine the functions, you can use a template:
#include <functional>
#include <iostream>
int addone(int x){
return x + 1;
}
int multtwo(int x){
return x * 2;
}
template <typename Func>
std::function<Func> combine(std::function<Func> f, std::function<Func> g){
auto tmp = [&](int x){ return f(g(x)); };
return std::function<Func>(tmp);
}
int main(){
auto h = combine<int(int)>(std::function<int(int)>(addone), std::function<int(int)>(multtwo));
std::cout << h(10) << "\n"; // Prints 21
}
You also don't need to specify the type, since the compiler can figure it out:
#include <functional>
#include <iostream>
int addone(int x){
return x + 1;
}
int multtwo(int x){
return x * 2;
}
template <typename func>
std::function<Func> combine(std::function<Func> f, std::function<Func> g){
auto tmp = [&](int x){ return f(g(x)); };
return std::function<Func>(tmp);
}
int main(){
auto h = combine(std::function<int(int)>(addone), std::function<int(int)>(multtwo));
std::cout << h(10) << "\n"; // Still prints 21
}
We can use templates to create a generic compose function that "combines" two unary functions using a lambda that captures the functions passed in, and returns it.
#include <functional>
#include <iostream>
template <typename Input, typename Output1, typename Output2>
std::function<Output2(Input)> compose(
std::function<Output2(Output1)> f,
std::function<Output1(Input)> g
) {
return [&f, &g](Input x) { return f(g(x)); };
}
int foo(int x) {
return x + 1;
}
int bar(int x) {
return x * 2;
}
int main() {
auto baz = compose<int, int, int>(foo, bar);
std::cout << baz(5) << std::endl;
auto wooble = compose<int, int, float>(
[](int x) { return static_cast<float>(x) + 1.5; },
[](int x) { return x * 3; }
);
std::cout << wooble(5) << std::endl;
return 0;
}
Do you want this?
int f1(int x) { return x + 1; }
int f2(int x) { return x * 2; }
int f3(int x) { return x * 3; }
int f4(int x) { return x - 5; }
int f5(int x) { return x + 9; }
int main() {
auto cf = combine<int>(f1, f2, f3, f4, f5);
std::cout << cf(5) << std::endl;
return 0;
}
Output:
40
Full code:
#include <functional>
#include <concepts>
#include <iostream>
template<typename T, typename NUM = int>
concept num_processor = requires (T t, NUM x) {
{t(x)} -> std::same_as<NUM>;
};
template<typename NUM, num_processor p>
NUM process(NUM v, p proc) {
return proc(v);
}
template<typename NUM, num_processor p, num_processor... Funs>
NUM process(NUM v, p proc, Funs... funs) {
return process(proc(v), funs...);
}
template<typename NUM, num_processor... Funs>
std::function<NUM (NUM)> combine(Funs... funs) {
return [...funs = funs] (NUM v) { return process(v, funs...); };
}
int f1(int x) { return x + 1; }
int f2(int x) { return x * 2; }
int f3(int x) { return x * 3; }
int f4(int x) { return x - 5; }
int f5(int x) { return x + 9; }
int main() {
auto cf = combine<int>(f1, f2, f3, f4, f5);
std::cout << cf(5) << std::endl;
return 0;
}
Compile with
-std=c++20 for gcc and /std:c++latest for msvc
Most other answers suggest std::function, but I'm wary of the runtime overhead it requires.
Since you don't need to select which functions are composed at runtime, you can do it without it. I'm using the same idea as #Elliot, but generalized for arbitrary types, and with hopefully nicer syntax:
#include <iostream>
#include <utility>
template <auto F0, auto ...F>
struct FuncList
{
static constexpr auto first = F0;
static constexpr bool have_next = true;
using next = FuncList<F...>;
};
template <auto F0>
struct FuncList<F0>
{
static constexpr auto first = F0;
static constexpr bool have_next = false;
};
template <typename F, typename ...P>
decltype(auto) Combine(P ...params) // Normally there would be `&&`, but I removed it allow casting to any function pointer type.
{
if constexpr (F::have_next)
return F::first(Combine<typename F::next, P &&...>(std::forward<P>(params)...));
else
return F::first(std::forward<P>(params)...);
}
int addone(int x)
{
return x + 1;
}
int multtwo(int x)
{
return 2 * x;
}
int main()
{
int (*ptr)(int) = Combine<FuncList<addone, multtwo>>;
std::cout << ptr(10) << '\n'; // 21
}
If you want to create automatically the functions, use 2pichar's answer with a for loop, but for an emulator you'd probably want something like opcode->int(*)(int). This could be done by some tree-like structure:
std::map<char, naive_opcode> opcodes;
struct naive_opcode {
std::map<char, naive_opcode> next;
int(* opcode_func)(int);
};
You'd work through this in some fashion like:
char data;
buf >> data;
naive_opcode opcode = opcodes[data];
while(!opcode.opcode_func){
buf >> data;
opcode = opcode.next[data];
}
opcode.opcode_func(param);
This of course ignores errors and does not include things like the instruction pointer and the .text section memory, rather replacing it with the buf buffer for illustrative purposes (In a real life example I'd expect this to be replaced by data=memory[ip]; ++ip;). This could then be combined with an implementation like:
#include <iostream>
int addone(int x){
return x + 1;
}
int multtwo(int x){
return x * 2;
}
template<int(* F)(int), int(* G)(int)>
int combined(int x){
return F(G(x));
}
int main(){
std::cout << combined<addone,multtwo>(10);
}
for which you could essentially just define the end node of naive_opcode as {{}, combined<addone,multtwo>}.
Unfortunately as I mentioned in my comment, this probably cannot be done automatically. The best you could do I recon is that you define something like:
std::vector<std::pair<const char*, int(*)(int)>> raw_opcodes = {{"\x10\x13", addone}, ...};
and then parse that into the tree like structure. As a brief side note: this might not be needed if all the opcodes are 1 byte (which I am unsure about since I am not familiar with NES). Then a simple std::map<char,int(*)(int)> opcodes will suffice instead of the convoluted naive_opcode (or better tree) implementation.
Looked it up and it seems that you wouldn't need the tree implementation, but a modification like this can be useful:
template<int(* F)(int)>
int combined(int x){
return F(x);
}
template<int(* F)(int), int(* A)(int), int(*... G)(int)>
int combined(int x){
return F(combined<A, G...>(x));
}
This allows for combining many effects into each other, rather than 2.

Can I give function pointer to template parameter?

Can I do something like this?
template<function_pointer_type pointer_name> struct structure1{
//here I call pointer_name(0)
};
void* function1 = [&](int a) {
return a * a;
}
structure1<function1> b;
I tried but it never compiled.
So, what's wrong with the code?
function1 is not constant expression so it cannot be used as template argument.
The lambda is not convertible to function pointer because it has a non-empty capture list.
Instead of function pointer, I suggest using a template parameter of function object, or std::function.
Function object:
template <class FunctionObject>
class A
{
private:
FunctionObject fun;
public:
A(FunctionObject f) : fun(f) {}
void f() { cout << fun(5) << endl; }
};
template <class FunctionObject>
A<FunctionObject> make_A(FunctionObject f)
{
return A<FunctionObject>(f);
}
std::function:
template <class FunctionType>
struct B
{
std::function<FunctionType> fun;
};
The usage:
void usage()
{
auto a = make_A([](int a) {return a*a; });
a.f();
B<int(int)> b;
b.fun = [&](int a) {return a*a; };
cout << b.fun(10) << endl;
}
To make this as absolutely similar to your original question as possible (using a lambda and a templated structure and so on):
#include <iostream>
template<typename F>
struct structure1 {
structure1(F x) : f(x) {}
int operator() (int a) { return f(a); };
F f;
};
int(*function1)(int) = [&](int a) {
return a * a;
};
int main() {
structure1< int(*)(int) > x(function1);
std::cout << x(4) << std::endl;
return 0;
}
I compiled and tested this with g++ -std=c++11 test.cpp

overload array operator with templates and pointers

The following code compiles (without warnings) on both clang++-2.9 and g++-4.6. However, the g++ binary Seg Faults, while the clang++ binary runs as intended.
What is the proper way to access template class data members through pointers when overloading []?
Here's the code:
#include <iostream>
template <typename T>
class A {
private:
T val1;
T val2;
public:
T& getVal1() { return val1; }
void setVal1(T aVal) { val1 = aVal; }
T& getVal2() { return val2; }
void setVal2(T aVal) { val2 = aVal; }
};
template <typename T>
class B {
private:
A<T>* aPtr;
public:
A<T>* getAPtr() { return aPtr; }
T& operator[](const int& key) {
if(key == 0) { T& res = getAPtr()->getVal1();
return res; }
else { T& res = getAPtr()->getVal2();
return res; }
}
};
int main()
{
B<int> foo;
foo[0] = 1;
int x = foo[0];
std::cout << foo[0] << " " << x << std::endl; // 1 1
}
You are returning a reference to a local variable (res). The reference won't be valid after returning from operator[]. It could be overwritten by other stuff. What really happens is Undefined: that is why compilers are allowed to eat your children or grow a moustache: Undefined Behaviour
You probably want to return by value.
Edit
Since you have a setter, you don't need the reference: See the solution live at http://ideone.com/oxslQ
Note: there was another problem with aPtr not being initialized. I proposed a simple constructor for that. _You might want to initialize this from elsewhere OR you need
assignment and copy constructors
or use a shared_ptr for aPtr
.
#include <iostream>
template <typename T>
class A
{
private:
T val1;
T val2;
public:
T getVal1()
{
return val1;
}
void setVal1(T aVal)
{
val1 = aVal;
}
T getVal2()
{
return val2;
}
void setVal2(T aVal)
{
val2 = aVal;
}
};
template <typename T>
class B
{
private:
A<T>* aPtr;
B(const B&); // TODO , disallow for now
B& operator=(const B&); // TODO , disallow for now
public:
B() : aPtr(new A<T>()) {}
~B() { delete aPtr; }
A<T>* getAPtr()
{
return aPtr;
}
T operator[](const int& key)
{
if(key == 0)
{
T res = getAPtr()->getVal1();
return res;
}
else
{
T res = getAPtr()->getVal2();
return res;
}
}
};
int main()
{
B<int> foo;
foo.getAPtr()->setVal1(1);
int x = foo[0];
std::cout << foo[0] << " " << x << std::endl; // 1 1
}
If you want to return by ref, then your A::getValX() functions should also return by ref, and your res variable inside B::operator should also be T& instead of T:
#include <iostream>
template <typename T>
class A {
private:
T val1;
T val2;
public:
T& getVal1() { return val1; }
void setVal1(T aVal) { val1 = aVal; }
T& getVal2() { return val2; }
void setVal2(T aVal) { val2 = aVal; }
};
template <typename T>
class B {
private:
A<T>* aPtr;
public:
A<T>* getAPtr() { return aPtr; }
T& operator[](const int& key) {
if(key == 0) { T& res = getAPtr()->getVal1();
return res; }
else { T& res = getAPtr()->getVal2();
return res; }
}
};
int main()
{
B<int> foo;
foo[0] = 1;
int x = foo[0];
std::cout << foo[0] << " " << x << std::endl; // 1 1
}
(Note that it will still crash at runtime, since aPtr isn't initialized anywhere.)
Your original code returns a reference to the local variable res, not to A::val1 / A::val2 as you probably intended. If res is a non-reference variable, then it will be a simple copy of the val1 / val2 value, that is only valid for inside the scope (in this case the function) where it was declared. So you need a reference here.

Variable user-defined parameter list in C++?

I'm looking for a simple way to create a user multi-parameter receiving function,
Here's some pseudo code
#include <iostream>
struct A {
int m_num;
};
void function(A* a, ...)
{
/* Pseudo-Code here */
for each parameter do
print a->m_num
end
}
int main()
{
A *a = new A();
A *b = new A();
A *c = new A();
a->m_num = 1;
b->m_num = 10;
c->m_num = 100;
function(a,b,c);
// delete everything
return 0;
}
I can't really use boost here, so if it's possible with standard C++ ( STL Allowed ), it would be great.
EDIT: The function parameters are heterogeneous
Old school plain C variadic arguments:
#include <cstdio>
#include <stdarg.h>
struct A {
A () : m_num (0) {}
A (int v) : m_num (v) {}
int m_num;
};
void function (A *a, ...)
{
va_list ap;
A *p = a;
va_start (ap, a);
while (p != NULL)
{
printf ("%d\n", p->m_num);
p = va_arg (ap, A*);
}
va_end (ap);
}
int main()
{
A a (1), b (10), c (100);
function (&a, &b, &c, NULL);
}
Another solution if arguments are of the same type (which is your case):
#include <cstdio>
struct A {
A () : m_num (0) {}
A (int v) : m_num (v) {}
int m_num;
};
void function (A *p, A *endp)
{
while (p != endp)
{
printf ("%d\n", p->m_num);
++p;
}
}
int main()
{
A a[3];
a[0].m_num = 1;
a[1].m_num = 10;
a[2].m_num = 100;
function (a, a + sizeof (a) / sizeof(a[0]));
}
Or even more C++-style, with iterators:
#include <cstdio>
#include <vector>
#include <list>
struct A {
A () : m_num (0) {}
A (int v) : m_num (v) {}
int m_num;
};
template <typename T>
void function (T p, T endp)
{
while (p != endp)
{
printf ("%d\n", p->m_num);
++p;
}
}
int main()
{
A a[3];
a[0].m_num = 1;
a[1].m_num = 10;
a[2].m_num = 100;
function (a, a + sizeof (a) / sizeof(a[0]));
std::vector<A> av (3);
av[0].m_num = 1;
av[1].m_num = 10;
av[2].m_num = 100;
function (av.begin (), av.end ());
std::list<A> al;
al.push_back (A (1));
al.push_back (A (10));
al.push_back (A (100));
function (al.begin (), al.end ());
}
The most straightforward way is to put your parameters into a std::vector. If they're non-homogeneous you can use a vector of boost::any or boost::variant.
Alternately design your interface like streams and use an insertion like operator/function that operators on one parameter at a time.
It would look something like this, alternately using a friend free-function.
struct A
{
int m_num;
};
struct printer
{
function& operator<<(A* a)
{
/* Pseudo-Code here */
print a->m_num
return *this;
}
};
int main()
{
A *a = new A();
A *b = new A();
A *c = new A();
a->m_num = 1;
b->m_num = 10;
c->m_num = 100;
printer function;
function << a << b << c;
// delete everything
return 0;
}
If every parameter going into function is an A, I'd do it with an array of A's, as in:
int main() {
A *abc[3];
for (int i=0;i<3;i++)
abc[i]=new A();
abc[0]->m_num=1;
abc[1]->m_num=10;
abc[2]->m_num=100;
function(abc,3);
}
void function(A *vals[],int count) {
for (int i=0;i<count;i++)
print vals[i]->m_num;
}
If you have a compiler recent enough to ship with std::tuple<> or std::tr1::tuple<>, you can do the following:
#include <cstddef>
#include <tuple>
#include <iostream>
struct A
{
int m_num;
};
template<typename T>
class function_impl
{
template<std::size_t N>
static void impl(T const& tup)
{
std::cout << std::get<N>(tup)->m_num << '\n';
}
template<std::size_t N>
struct recurse_helper
{
static void invoke(T const& tup)
{
function_impl<T>::template impl<N>(tup);
recurse_helper<N + 1u>::invoke(tup);
}
};
template<>
struct recurse_helper<std::tuple_size<T>::value>
{
static void invoke(T const&) { }
};
public:
static void invoke(T const& tup)
{
recurse_helper<0u>::invoke(tup);
}
};
template<typename T>
void function(T const& tup)
{
function_impl<T>::invoke(tup);
}
int main()
{
A* a = new A();
a->m_num = 1;
A* b = new A();
b->m_num = 10;
A* c = new A();
c->m_num = 100;
function(std::tie(a, b, c));
delete c;
delete b;
delete a;
}
Note that function actually takes a singular argument, a tuple<>, rather than multiple arguments. But, unlike any varargs-based solution, this is completely type-safe.
Also note that the implementation here would be much simpler if you could use Boost.Fusion...
As a supplement.
In C++0x, you could use variadic-template to implement your function recursively:
// Just to make the compiler happy.
template <typename T>
void function(T a) = delete;
// Base case
template <>
void function(A* a) {
printf("%d\n", a->m_num);
}
// Recursion
template <typename T, typename... Args>
void function(T a, Args... args) {
function(a);
function(args...);
}
But this will generate N functions if it accepts N parameters. Alternatively, you could use an initializer_list:
void function(std::initializer_list<A*> args) {
for (auto cit = args.begin(); cit != args.end(); ++ cit)
printf("%d\n", (*cit)->m_num);
}
but you need to call function as
function({a,b,c});
// ^ ^