I give the following example to illustrate my question:
class Abc
{
public:
int height();
int width();
int area();
};
typedef std::vector<class Abc> AbcArray;
void obtain_selected_list_based_on_area(AbcArray& objArray,
std::vector<int> &listIndexArray)
{
std::vector<int> areaArray;
for(int i=0; i<objArray.size(); i++)
areaArray.push_back(objArray[i].area());
function_select_list(areaArray,listIndexArray);
}
void obtain_selected_list_based_on_height(AbcArray& objArray,
std::vector<int> &listIndexArray)
{
std::vector<int> areaArray;
for(int i=0; i<objArray.size(); i++)
areaArray.push_back(objArray[i].height());
function_select_list(areaArray,listIndexArray);
}
void obtain_selected_list_based_on_width(AbcArray& objArray,
std::vector<int> &listIndexArray)
{
std::vector<int> areaArray;
for(int i=0; i<objArray.size(); i++)
areaArray.push_back(objArray[i].width());
function_select_list(areaArray,listIndexArray);
}
As you can see from the above code snippet, we decide to select the list based on three different criteria. In order to do that, we have to write three functions: obtain_selected_list_based_on_area
, obtain_selected_list_based_on_height
, and obtain_selected_list_based_on_width
.
I just wondering how I can simplify it.
For me there one solutions. One is to use function pointer:
void obtain_select_list(AbcArray& objArray, std::vector<int> &listSel, FUN fun)
{
std::vector<int> areaArray;
for(int i=0; i<objArray.size(); i++)
areaArray.push_back(objArray[i].width());
function_select_list(areaArray,listIndexArray);
}
However, I cannot make it work because the function pointer is pointing to the member of a class.
Do you have some ideas on how to make it work? Moreover, any other solutions for this problem?
Not exactly function pointers, but rather class method pointers.
Additionally, using C++11 range iteration makes the resulting syntax much simpler, and easier to read:
void obtain_selected_list_based_on(AbcArray& objArray,
std::vector<int> &listIndexArray,
int (Abc::*get_something)())
)
{
std::vector<int> areaArray;
for (const auto &v:objArray)
areaArray.push_back((v.*get_something)());
function_select_list(areaArray,listIndexArray);
}
This can be invoked as:
obtain_selected_list_based_on(objArray,
listIndexArray,
&Abc::height);
// or
obtain_selected_list_based_on(objArray,
listIndexArray,
&Abc::width);
// or
obtain_selected_list_based_on(objArray,
listIndexArray,
&Abc::area);
Your class methods should probably be const
themselves, which would change the parameter type to int (Abc::*get_something)() const
.
I think something like this should work.
void <template T> obtain_select_list(AbcArray& objArray, std::vector<int> &listSel, T (*fun)(const Abc&))
{
std::vector<T> areaArray;
for(int i=0; i<objArray.size(); i++)
areaArray.push_back(fun(objArray[i]));
function_select_list(areaArray,listIndexArray);
}
Just to be more general i used a template one, so that if you need the function to return things different from an int you can still use it.
I wasn't able to test it, it compiles but i don't know it if works, but it should.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.