Thread: Example of a C++ vector whose elements are functions.

  1. #1
    Registered User FortranLevelC++'s Avatar
    Join Date
    May 2013
    Location
    United States
    Posts
    81

    Example of a C++ vector whose elements are functions.

    Finally I have built a C++ vector whose elements are functions that accept and modify arguments. With this method it is very easy to iterate over a collection of functions. ( In this example all function elements of the vector have the same kind of arguments, but even if the arguments of the functions are very different, you can at least make the functions read their arguments from a disk file.)

    I am listing the code below, at least on the surface it is compiling and executing without error, but if you can find any hidden errors please let me know.

    I haven't yet learned the lambdas of C++11, but if you know how to use lambdas or other advanced methods to create better data structures that make it possible to parametrize functions in a manner that can be used to iterate over a family of functions, please let me know. Another point of lambdas might be the capability to generate or "write" many thousands of functions automatically (as code!?!? ) real time, depending on the events that are happening. Perhaps, this way, a library of functions can be generated automatically or at least semi-automatically according to incoming experimental data, for later use, and then a map data structure can also be used to keep track of the family of functions that will be placed in a vector data structure. Since the map is in some sense the dual of the vector or array, this can make it possible to write a very effective program. If you have many thousands of functions to choose from in the logic of the program, you cannot afford to write that many lines of if statements manually, but iteration over the functions will do that indirectly.

    Basically I have imitated part of this code from the Internet, which creates an array whose elements are functions:

    Array of functions? - C++ Forum

    Apparently, the secret of their code above, is to use a typedef statement to introduce the form of the functions at the very beginning, and I was able to imitate almost exactly the same syntax to create a vector whose elements are functions.

    Here is the self-contained program that I wrote to create a vector of functions:


    Code:
    #include <stdio.h>      
    #include <stdlib.h>  
    #include <iomanip>
    #include <fstream>
    #include <iostream>
     #include <cstring>
    #include <sstream>
    #include <string>
    #include <string.h>
    
    
    #include <math.h>
    #include <vector>
    #include <map>
    
    using namespace std;
    
    typedef void (*FunctionWithArrayAsArgument) (double a [], double coefficient,  int size);
    
    void function1(double a [], double coefficient,  int size)
        {
             for(int i=0; i<size; i++)
             {    
                
                 a[i]=coefficient*a[i]*pow(i,1);
             }
            }
    
    
    void function2(double a [], double coefficient,  int size)
        {
             for(int i=0; i<size; i++)
             {
                
                  a[i]=coefficient*a[i]*pow(i,2);
             }
                
             
            }
    
    
    void function3(double a [], double coefficient,  int size)
        {
             for(int i=0; i<size; i++)
             {
                
                 a[i]=coefficient*a[i]*pow(i,3);
                
             }
            }
    
    
    int main()
    {       
        int size = 5;
        double Array[size];
        double MyCoefficient =2;
     
        for(int i=0; i<size; i++) 
        {
            Array[i]=i;
        }
    
    
            vector<FunctionWithArrayAsArgument> Vector_Of_Functions;
    
        Vector_Of_Functions.push_back(function1 );
        Vector_Of_Functions.push_back(function2 );
        Vector_Of_Functions.push_back(function3 );
        
            cout<< "Before function calls the Array is initialized as follows:" << endl;
        
            for (int j=0; j<size; j++) // Here "size" is the number of scalar elements of the array argument of functions, 
        {            // it's not the size of the vector whose elements are functions.
              cout << Array[j] << endl;
        }                 
    
    
        vector<FunctionWithArrayAsArgument>::iterator end = Vector_Of_Functions.end(); 
            
           for(vector<FunctionWithArrayAsArgument>::iterator itr=Vector_Of_Functions.begin();  itr != end; ++itr )
           {  
            size_t Index_Of_Function = itr - Vector_Of_Functions.begin();
            Vector_Of_Functions[Index_Of_Function](Array, MyCoefficient, size);
            cout << "After the vector function number " <<Index_Of_Function  << 
                    " is called the Array elements are as follows: " << endl;
            for (int j=0; j<size; j++) 
            {
                    cout << Array[j] << endl;
            }
         }
        
    }
    Last edited by FortranLevelC++; 05-10-2013 at 02:25 AM.

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by FortranLevelC++ View Post
    Apparently, the secret of their code above, is to use a typedef statement to introduce the form of the functions at the very beginning, and I was able to imitate almost exactly the same syntax to create a vector whose elements are functions.
    A typedef is a technique to make it easier and more convenient to achieve the intended result. However, although a typedef is convenient and good practice, it is not mandatory.
    Code:
         vector<FunctionWithArrayAsArgument> Vector_Of_Functions;
    with
    Code:
         vector<void (*)(double [], double, int)> Vector_Of_Functions;
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    For starters, you need to indent your code properly. I see this part:
    Code:
    vector<FunctionWithArrayAsArgument>::iterator end = Vector_Of_Functions.end();
    
    for(vector<FunctionWithArrayAsArgument>::iterator itr=Vector_Of_Functions.begin();  itr != end; ++itr )
    {
        size_t Index_Of_Function = itr - Vector_Of_Functions.begin();
        Vector_Of_Functions[Index_Of_Function](Array, MyCoefficient, size);
        cout << "After the vector function number " <<Index_Of_Function  << 
            " is called the Array elements are as follows: " << endl;
        for (int j=0; j<size; j++)
        {
            cout << Array[j] << endl;
        }
    }
    Since you are already iterating over the vector using an iterator, it seems pointless to then compute the index so as to access the element using the index. Rather, use the iterator:
    Code:
    (*itr)(Array, MyCoefficient, size);
    However, since you want to print the index, iterate using the index instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I will also point out that instead of

    vector<FunctionWithArrayAsArgument>::iterator itr=Vector_Of_Functions.begin()

    you can write

    auto itr=Vector_Of_Functions.begin()

    Also, instead of using C arrays (ie double[]), it would be better to use C++ arrays such as std::array or std::vector and their at function. It helps debug your code tremendously in many cases. See more here: SourceForge.net: Safer arrays in Cpp - cpwiki

    Also, regarding lambdas... they are not exactly as revolutionary as you seem to think they are. They are inline functions and nothing more. They can't be used to dynamically generate code. It won't reduce the number of if statements. It will just put more code into the same place. They are syntactic sugar.
    But I can give you syntax for them:

    Code:
    [capture list](parameter list) -> return type { body }
    The rest you can google.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User FortranLevelC++'s Avatar
    Join Date
    May 2013
    Location
    United States
    Posts
    81
    Quote Originally Posted by grumpy View Post
    vector<FunctionWithArrayAsArgument> Vector_Of_Functions;
    [/code]
    with
    Code:
         vector<void (*)(double [], double, int)> Vector_Of_Functions;

    Many thanks. This syntax was rather too abstract for my psychology, and this is why I imagined that a typedef was obligatory. I simply could not comprehend that when I create the vector I can get away with a "nameless" type inside the brackets < >. The syntax " (* ) " requires a good understanding of C++, which I don' t have for the moment.

    Anyway, the ability of C++ to create a vector of functions to iterate is astounding, and I already have very effective code even with minimal knowledge of C++.

  6. #6
    Registered User FortranLevelC++'s Avatar
    Join Date
    May 2013
    Location
    United States
    Posts
    81
    Quote Originally Posted by Elysia View Post
    I will also point out that instead of

    vector<FunctionWithArrayAsArgument>::iterator itr=Vector_Of_Functions.begin()

    you can write

    auto itr=Vector_Of_Functions.begin()

    Also, instead of using C arrays (ie double[]), it would be better to use C++ arrays such as std::array or std::vector and their at function. It helps debug your code tremendously in many cases. See more here: SourceForge.net: Safer arrays in Cpp - cpwiki

    Also, regarding lambdas... they are not exactly as revolutionary as you seem to think they are. They are inline functions and nothing more. They can't be used to dynamically generate code. It won't reduce the number of if statements. It will just put more code into the same place. They are syntactic sugar.
    But I can give you syntax for them:

    Code:
    [capture list](parameter list) -> return type { body }
    The rest you can google.
    Thanks!

  7. #7
    Registered User FortranLevelC++'s Avatar
    Join Date
    May 2013
    Location
    United States
    Posts
    81
    Quote Originally Posted by laserlight View Post

    Since you are already iterating over the vector using an iterator, it seems pointless to then compute the index so as to access the element using the index. Rather, use the iterator:
    Code:
    (*itr)(Array, MyCoefficient, size);
    However, since you want to print the index, iterate using the index instead.
    Many thanks! Since I don't have a good understanding of iterators, I did not know to apply it so directly like the statement (*itr)(Array, MyCoefficient, size) that you suggested. The only reason I was printing the artificial integer values for the iterator there was for my primitive debugging/testing purposes, but now that I can see that the vector syntax is correct, I will immediately use your version in real code.
    Last edited by FortranLevelC++; 05-10-2013 at 07:51 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Vector elements disappearing
    By stobbz in forum C++ Programming
    Replies: 6
    Last Post: 04-19-2011, 07:23 PM
  2. Replace elements in vector
    By franse in forum C++ Programming
    Replies: 2
    Last Post: 11-18-2008, 12:46 PM
  3. deleting elements of a vector
    By strickey in forum C++ Programming
    Replies: 11
    Last Post: 02-09-2005, 11:19 AM
  4. Vector elements
    By strickey in forum C++ Programming
    Replies: 5
    Last Post: 02-04-2005, 10:30 AM
  5. Sorting out vector elements
    By strickey in forum C++ Programming
    Replies: 2
    Last Post: 01-20-2005, 04:41 AM