Function Pointers by Reference - c++

Good Day everybody, I am creating a List class in order to be able to manipulate data like in python, but in c++.
I came up with an idea. Basically a method that goes through every node, and deletes it if it meets a specific condition. But I wanted that condition to be determined by the user of the library, so I implemented a pointer to a bool function, that takes one template data (same type as the List) as its only parameter.
So far, I managed to run this...
.h file:
int delIf(bool (*)(T));
.cpp file:
template <typename T>
int List<T>::delIf(bool (*ptr)(T)){
int tot=0;
T aux;
for (int i=0;i<tam;i++)
{
aux=(*this)[i]; //Ive overloaded the [], and it works fine
if ((*ptr)(aux))
{
tot++;
this->del(i);
}
}
return tot;
}
main.cpp:
#include <iostream>
#include "lists.cpp"
using namespace std;
bool check(int);
int main()
{
List<int> a;
for (int i=0;i<10;i++)
a.push(i);
a.delIf(&check);
return 0;
}
bool check(int a){
if (a%2==0)
return true;
else
return false;
}
This works fine, however, I was wondering if its possible to overload the delIf method so that it takes not a pointer to a function as parameter, but a reference to it, so the user of the library could call:
delIf(check); //No '&' required
Instead of the
delIf( & check);
That is currently mandatory. Ive tried changing the prototype to something like:
int delIf( (bool (*)(T)) & );
but I keep getting errors.
Thanks in Advance Everybody.

Your premise is false. You don't need an & in front of a function to pass it to delIf. The name of a function decays into a pointer to the function almost everywhere it is used in an expression. (Including when you call the function!) In fact, the only place it doesn't is when it is used as an argument to & - so
func
&func
have exactly the same type and value.
Having said that, yes you can pass a reference. First rule of pointers to functions - write a typedef
typedef bool pred_t(T);
void delIf( pred_t& pred );
But! I strongly encourage you to write delIf as a function template, and allow anything which can be called with a T, and has a function result which can be implicitly converted to bool.
template <typename Pred>
void delIf(Pred pred) {
...
}
That will allow use with capturing lambdas, and functors in general.
Also, what is this CPP file of which you speak? Templates have to be implemented in the header file. See the answers to this question.
(Note: "Pred" is short for "predicate" which is what the standard calls this sort of function.)

Related

Modify values of elements of an Eigen Matrix [duplicate]

I am working with a library which exposes an interface to work with. One of the functions of this library is like this :
template <int a>
void modify(){}
I have to modify parameters from 1 to 10 i.e. call modify with with template arguments from 1 to 10. For that I wrote this code (a basic version of code, actual code is much larger).
for(int i=0; i<10; i++){
modify<i>();
}
On compilation I receive the following error
error: 'i' cannot appear in constant-expression
After going through some links on the internet, I came to know that I cannot pass any value as template argument which is not evaluated at compile time.
My question are as follows:
1. Why can't compiler evaluate i at compile time?
2. Is there any other to achieve the objective I am trying to achieve without changing the API interface?
There is another thing I want to do. Call modify as modify where VAR is the output of some functional computation. How can I do that?
What is the value of i (that is not a constant) at compile time? There is no way to answer unless executing the loop. But executing is not "compiling"
Since there is no answer, the compiler cannot do that.
Templates are not algorithm to be executed, but macros to be expanded to produce code.
What you can do is rely on specialization to implement iteration by recursion, like here:
#include <iostream>
template<int i>
void modify()
{ std::cout << "modify<"<<i<<">"<< std::endl; }
template<int x, int to>
struct static_for
{
void operator()()
{ modify<x>(); static_for<x+1,to>()(); }
};
template<int to>
struct static_for<to,to>
{
void operator()()
{}
};
int main()
{
static_for<0,10>()();
}
Note that, by doing this, you are, in fact, instantiating 10 functions named
modify<0> ... modify<9>, called respectively by static_for<0,10>::operator() ... static_for<9,10>::operator().
The iteration ends because static_for<10,10> will be instantiated from the specialization that takes two identical values, that does nothing.
"Why can't compiler evaluate i at compile time?"
That would defeat the purpose of templates. Templates are there for the case where the source code looks the same for some set of cases, but the instructions the compiler needs to generate are different each time.
"Is there any other to achieve the objective I am trying to achieve without changing the API interface?"
Yes, look at Boost.MPL.
However I suspect the right answer here is that you want to change the API. It depends on the internals of the modify function. I know you have it's source, because templates must be defined in headers. So have a look why it needs to know i at compile time and if it does not, it would be best to replace (or complement if you need to maintain backward compatibility) it with normal function with parameter.
Since you asked for an answer using Boost.MPL:
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <iostream>
template <int N>
void modify()
{
std::cout << N << '\n';
}
// You need to wrap your function template in a non-template functor
struct modify_t
{
template <typename N>
void operator()(N)
{
modify<N::value>();
}
};
int main()
{
namespace mpl = boost::mpl;
mpl::for_each< mpl::range_c<int,0,10> >( modify_t() ); // prints 0 to 9
}
Without using struct or Boost it can also be done :
#include <iostream>
#include <utility>
template <int a>
void modify()
{
std::cout<<a<<",";
}
template<int i,size_t... t>
constexpr inline void CT_for_impl(std::integer_sequence<size_t,t...>)
{
bool kai[]= { (modify<i+t>(), false)...};
}
template<int i,int n>
constexpr inline void CT_for()
{
CT_for_impl<i>(std::make_index_sequence<n-i+1>());
}
int main()
{
CT_for<-5,5>();
return 0;
}
Given you want to call the functions at run-time by their index and you can't change the API, you can consider type-erasure:
std::vector<std::function<void(int)> > func;
func.push_back(modify<1>);
func.push_back(modify<2>);
//... and so on ...
func.push_back(modify<10>);
for(int i=0; i<10; ++i)
{
func[i](); //calls modify<i+1>();
}
Some points to mention:
That's not what templates are primarily for, but it's a way to bring a static library to the run-time world. The basic requirement for this is that one works with homogeneous types (--if modify<7>() would return, say, a std::string the whole approach would break).
The previous solution using type-erasure has an overhead. One can maybe get it faster by using function pointers, but still it will always be slower than calling the functions at compile time.
One can (and should) also wrap the push_backs into another iterative static function to avoid the manual calls.
solution to error: 'i' cannot appear in constant-expression for the above problem
To read about constexpr click this link
#include <iostream>
using namespace std;
template <typename T>
void modify(T a)
{
cout<<a<<endl; //to check if its working
}
//func converts int a into const int a
constexpr int func(int a)
{
return a;
}
int main(){
for(int i=0; i<10; i++){
modify(func(i));//here passing func(i) returned value which can be used as template argument now as it is converted to constexpr
}
return 0;
}

Accessing Variant Elements by Index: What does the documentation tell me? [duplicate]

I am working with a library which exposes an interface to work with. One of the functions of this library is like this :
template <int a>
void modify(){}
I have to modify parameters from 1 to 10 i.e. call modify with with template arguments from 1 to 10. For that I wrote this code (a basic version of code, actual code is much larger).
for(int i=0; i<10; i++){
modify<i>();
}
On compilation I receive the following error
error: 'i' cannot appear in constant-expression
After going through some links on the internet, I came to know that I cannot pass any value as template argument which is not evaluated at compile time.
My question are as follows:
1. Why can't compiler evaluate i at compile time?
2. Is there any other to achieve the objective I am trying to achieve without changing the API interface?
There is another thing I want to do. Call modify as modify where VAR is the output of some functional computation. How can I do that?
What is the value of i (that is not a constant) at compile time? There is no way to answer unless executing the loop. But executing is not "compiling"
Since there is no answer, the compiler cannot do that.
Templates are not algorithm to be executed, but macros to be expanded to produce code.
What you can do is rely on specialization to implement iteration by recursion, like here:
#include <iostream>
template<int i>
void modify()
{ std::cout << "modify<"<<i<<">"<< std::endl; }
template<int x, int to>
struct static_for
{
void operator()()
{ modify<x>(); static_for<x+1,to>()(); }
};
template<int to>
struct static_for<to,to>
{
void operator()()
{}
};
int main()
{
static_for<0,10>()();
}
Note that, by doing this, you are, in fact, instantiating 10 functions named
modify<0> ... modify<9>, called respectively by static_for<0,10>::operator() ... static_for<9,10>::operator().
The iteration ends because static_for<10,10> will be instantiated from the specialization that takes two identical values, that does nothing.
"Why can't compiler evaluate i at compile time?"
That would defeat the purpose of templates. Templates are there for the case where the source code looks the same for some set of cases, but the instructions the compiler needs to generate are different each time.
"Is there any other to achieve the objective I am trying to achieve without changing the API interface?"
Yes, look at Boost.MPL.
However I suspect the right answer here is that you want to change the API. It depends on the internals of the modify function. I know you have it's source, because templates must be defined in headers. So have a look why it needs to know i at compile time and if it does not, it would be best to replace (or complement if you need to maintain backward compatibility) it with normal function with parameter.
Since you asked for an answer using Boost.MPL:
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <iostream>
template <int N>
void modify()
{
std::cout << N << '\n';
}
// You need to wrap your function template in a non-template functor
struct modify_t
{
template <typename N>
void operator()(N)
{
modify<N::value>();
}
};
int main()
{
namespace mpl = boost::mpl;
mpl::for_each< mpl::range_c<int,0,10> >( modify_t() ); // prints 0 to 9
}
Without using struct or Boost it can also be done :
#include <iostream>
#include <utility>
template <int a>
void modify()
{
std::cout<<a<<",";
}
template<int i,size_t... t>
constexpr inline void CT_for_impl(std::integer_sequence<size_t,t...>)
{
bool kai[]= { (modify<i+t>(), false)...};
}
template<int i,int n>
constexpr inline void CT_for()
{
CT_for_impl<i>(std::make_index_sequence<n-i+1>());
}
int main()
{
CT_for<-5,5>();
return 0;
}
Given you want to call the functions at run-time by their index and you can't change the API, you can consider type-erasure:
std::vector<std::function<void(int)> > func;
func.push_back(modify<1>);
func.push_back(modify<2>);
//... and so on ...
func.push_back(modify<10>);
for(int i=0; i<10; ++i)
{
func[i](); //calls modify<i+1>();
}
Some points to mention:
That's not what templates are primarily for, but it's a way to bring a static library to the run-time world. The basic requirement for this is that one works with homogeneous types (--if modify<7>() would return, say, a std::string the whole approach would break).
The previous solution using type-erasure has an overhead. One can maybe get it faster by using function pointers, but still it will always be slower than calling the functions at compile time.
One can (and should) also wrap the push_backs into another iterative static function to avoid the manual calls.
solution to error: 'i' cannot appear in constant-expression for the above problem
To read about constexpr click this link
#include <iostream>
using namespace std;
template <typename T>
void modify(T a)
{
cout<<a<<endl; //to check if its working
}
//func converts int a into const int a
constexpr int func(int a)
{
return a;
}
int main(){
for(int i=0; i<10; i++){
modify(func(i));//here passing func(i) returned value which can be used as template argument now as it is converted to constexpr
}
return 0;
}

Having a function inside for_each statement

I keep on getting error message while trying to pass a function inside a for_each loop.. I have a vector and i used for_each loop to go through the rows in that vector, Now I need a function to do something
Example this is what I am trying to achieve:
void DataPartitioning::doSomething()
{
for_each (label.begin(), label.end(), addToTemporaryVector());
}
void DataPartitioning::addToTemporaryVector()
{
cout<<"sucess";
}
But I get an error message saying: error: invalid use of void expression both of them are in same class.
Since it's a member function, you'll need to wrap it in a functor that calls it on an object; presumably the same object that doSomething was called on:
for_each(label.begin(), label.end(), [this](whatever const &){addToTemporaryVector();});
where whatever is the value type of the container.
It might be clearer as a regular for-loop:
for (whatever const & thing : label) {
addToTemporaryVector();
}
This assumes you're not stuck with a pre-C++11 compiler. If you are, it requires rather more gibberish:
for_each(label.begin(), label.end(),
std::bind1st(std::mem_fun(&DataPartitioning::addToTemporaryVector), this));
I'm not entirely sure whether that will work with a function like yours that doesn't take an argument; but presumably your real code does take an argument to do something with each element.
You need to use a struct as here:
http://en.cppreference.com/w/cpp/algorithm/for_each
#include <iostream>
#include<string>
#include <vector>
#include <algorithm>
using namespace std;
struct Operation
{
void operator()(string n) { cout<<"success"<<endl; }
};
int main() {
vector<string> vInts(10,"abc");
std::for_each(std::begin(vInts), std::end(vInts), Operation());
// your code goes here
return 0;
}
Note that the input of the operator has to be the same as the type in the vector. (string in this example, int in the link)
The addToTemporaryVector function does not use this. So you can declare it as static.
Also, it should take as argument the template type of label
Declaration:
static void addToTemporaryVector(const SomeType & item);
Then just do:
//No parentheses to the function pointer
for_each (label.begin(), label.end(), addToTemporaryVector);

Passing a variable as a template argument

I am working with a library which exposes an interface to work with. One of the functions of this library is like this :
template <int a>
void modify(){}
I have to modify parameters from 1 to 10 i.e. call modify with with template arguments from 1 to 10. For that I wrote this code (a basic version of code, actual code is much larger).
for(int i=0; i<10; i++){
modify<i>();
}
On compilation I receive the following error
error: 'i' cannot appear in constant-expression
After going through some links on the internet, I came to know that I cannot pass any value as template argument which is not evaluated at compile time.
My question are as follows:
1. Why can't compiler evaluate i at compile time?
2. Is there any other to achieve the objective I am trying to achieve without changing the API interface?
There is another thing I want to do. Call modify as modify where VAR is the output of some functional computation. How can I do that?
What is the value of i (that is not a constant) at compile time? There is no way to answer unless executing the loop. But executing is not "compiling"
Since there is no answer, the compiler cannot do that.
Templates are not algorithm to be executed, but macros to be expanded to produce code.
What you can do is rely on specialization to implement iteration by recursion, like here:
#include <iostream>
template<int i>
void modify()
{ std::cout << "modify<"<<i<<">"<< std::endl; }
template<int x, int to>
struct static_for
{
void operator()()
{ modify<x>(); static_for<x+1,to>()(); }
};
template<int to>
struct static_for<to,to>
{
void operator()()
{}
};
int main()
{
static_for<0,10>()();
}
Note that, by doing this, you are, in fact, instantiating 10 functions named
modify<0> ... modify<9>, called respectively by static_for<0,10>::operator() ... static_for<9,10>::operator().
The iteration ends because static_for<10,10> will be instantiated from the specialization that takes two identical values, that does nothing.
"Why can't compiler evaluate i at compile time?"
That would defeat the purpose of templates. Templates are there for the case where the source code looks the same for some set of cases, but the instructions the compiler needs to generate are different each time.
"Is there any other to achieve the objective I am trying to achieve without changing the API interface?"
Yes, look at Boost.MPL.
However I suspect the right answer here is that you want to change the API. It depends on the internals of the modify function. I know you have it's source, because templates must be defined in headers. So have a look why it needs to know i at compile time and if it does not, it would be best to replace (or complement if you need to maintain backward compatibility) it with normal function with parameter.
Since you asked for an answer using Boost.MPL:
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <iostream>
template <int N>
void modify()
{
std::cout << N << '\n';
}
// You need to wrap your function template in a non-template functor
struct modify_t
{
template <typename N>
void operator()(N)
{
modify<N::value>();
}
};
int main()
{
namespace mpl = boost::mpl;
mpl::for_each< mpl::range_c<int,0,10> >( modify_t() ); // prints 0 to 9
}
Without using struct or Boost it can also be done :
#include <iostream>
#include <utility>
template <int a>
void modify()
{
std::cout<<a<<",";
}
template<int i,size_t... t>
constexpr inline void CT_for_impl(std::integer_sequence<size_t,t...>)
{
bool kai[]= { (modify<i+t>(), false)...};
}
template<int i,int n>
constexpr inline void CT_for()
{
CT_for_impl<i>(std::make_index_sequence<n-i+1>());
}
int main()
{
CT_for<-5,5>();
return 0;
}
Given you want to call the functions at run-time by their index and you can't change the API, you can consider type-erasure:
std::vector<std::function<void(int)> > func;
func.push_back(modify<1>);
func.push_back(modify<2>);
//... and so on ...
func.push_back(modify<10>);
for(int i=0; i<10; ++i)
{
func[i](); //calls modify<i+1>();
}
Some points to mention:
That's not what templates are primarily for, but it's a way to bring a static library to the run-time world. The basic requirement for this is that one works with homogeneous types (--if modify<7>() would return, say, a std::string the whole approach would break).
The previous solution using type-erasure has an overhead. One can maybe get it faster by using function pointers, but still it will always be slower than calling the functions at compile time.
One can (and should) also wrap the push_backs into another iterative static function to avoid the manual calls.
solution to error: 'i' cannot appear in constant-expression for the above problem
To read about constexpr click this link
#include <iostream>
using namespace std;
template <typename T>
void modify(T a)
{
cout<<a<<endl; //to check if its working
}
//func converts int a into const int a
constexpr int func(int a)
{
return a;
}
int main(){
for(int i=0; i<10; i++){
modify(func(i));//here passing func(i) returned value which can be used as template argument now as it is converted to constexpr
}
return 0;
}

Calling the function pointed by a Pointer-to-Member-Function from within a struct

I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();