Arrays as Argument

Hi

I'm trying to implement a constructor that will take an array as a parameter. The class to which the constructor applies has (non-class) functions, which is called by a function pointer.

Some of the functions require only the first element of the array as input while the other function require the entire array. The code below shows just one of each function for illustration.

I'm having problems understanding the syntax of passing arrays as arguments.

My understanding is that reference to the array actually refers only to the first element of the array. ie. say for

 
double Strike[2];


then creating a PayOff object callPayOff with

 
PayOff callPayOff(Strike, call);


this makes sense as Strike used here means Strike[0].

However
 
PayOff callPayOff(Strike[0], call);

doesn't work when I thought given the above, Strike[ and Strike[0] should then be interchangeable.

So on the other hand, if Strike actually means the entire array,
 
PayOff doubledigitalPayOff(Strike, doubledigital);

doesn't work (error (ln 9 of Main below): no instance of constructor matches the argument list) ... despite Strike being declared as an array of size 2 already?

Header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PayOff
{
public:
	typedef double (*FunctionPtr) (double, double);
	PayOff(double Strike_[], FunctionPtr FunctionPtr_);
	double operator()(double Spot) const;

private:
	double Strike[2];
	FunctionPtr functionPtr;

};
double call(double Spot, double Strike); 
double doubledigital(double Spot, double Strike[2]);


Source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
PayOff::PayOff(double Strike_[], FunctionPtr FunctionPtr_) 
{
	Strike[2] = Strike_[2];
	functionPtr = FunctionPtr_;
}

double PayOff::operator()(double Spot) const
{
	return functionPtr(Spot, Strike[2]);
}

double call(double Spot, double Strike) 
{
	return max(Spot - Strike, 0); 
}
double doubledigital(double Spot, double Strike[2])
{
	// 1) determine which is the lower strike and higher strike
	// 2) calculate the payoff
	
	// 1)
	double *strikePtr;
	double upperStrike, lowerStrike;
	
	// and so here Strike[i] refers to ith element in Strike array
	if(Strike[0] > Strike[1])
	{
		upperStrike = Strike[0];
		lowerStrike = Strike[1];
	}
	else if(Strike[0] < Strike[1])
	{
		upperStrike = Strike[1];
		lowerStrike = Strike[0];
	}
	else
		throw("strikes can't be of equal value");
	
	// 2)
	if ((Spot > upperStrike) || (Spot < lowerStrike))
		return 0;
	else 
		return 1;
} 


Main
1
2
3
4
5
6
7
8
9
double Strike[2];

cout << "\nStrike 1 ($): \n";
cin >> Strike[0];
cout << "\nStrike 2 ($): \n";
cin >> Strike[1];

PayOff callPayOff(Strike, call);
PayOff doubledigitalPayOff(Strike, doubledigital);

On line 9, your function pointer doubledigital is to a function that takes a double[] as its second argument, but the constructor takes a function pointer with just a normal double as its second argument.
Last edited on
thanks

adjusting the function pointer declaration at Header, ln 4 fixes this, but then using the function pointer at Source, ln 9 results in Strike[2] having an incompatibility error.

why is this? shouldn't Source, ln 9 be consistent with the adjustment to the function pointer declaration?
for example, if say I comment out double call(double Spot, double Strike) /* ... */ (which takes a double rather than a double[], it doesn't make a difference.

also if I want to generally be able to create a PayOff object that can accept double or double[], does this mean I have to declare two different constructors each with its own function pointer and operator()? (I just want to stick with the function pointer structure for now so I can understand how it works).
If you want to pass the array on line 9, just pass Strike. Strike[2] is accessing out of bounds memory on your array, anyway.

If you want to constructor to take either a double or double[], yes you will need to make two separate constructors.
An array is a pointer to the first element, not a reference.
void f(double x[]); is basically the same as
void f(double *x);
ok, I think I'm passing the array correctly now (or at least there's no obvious errors coming up).

For the constructors, I have declared a non-array parameter constructor (with a non-array function pointer) and an array constructor (with a array function pointer).

However as both constructors are for the same class, do they have to both use the same operator()? If so, how do you determine which function pointer to use? Otherwise, how does the compiler know which operator() to use?

thanks for your help

Header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class PayOff
{
public:
	
	typedef double (*FunctionPtr) (double, double);
	typedef double (*arrFunctionPtr) (double, double[]);
	
	PayOff(double Strike_, FunctionPtr FunctionPtr_);
	PayOff(double Strike_[], arrFunctionPtr arrFunctionPtr_);

	double operator()(double Spot) const;

private:
	double Strike;
	double arrStrike[2];

	FunctionPtr functionPtr;
	arrFunctionPtr arrfunctionPtr;

};

double call(double Spot, double Strike); 
double doubledigital(double Spot, double Strike[2]);


Source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
PayOff::PayOff(double Strike_, FunctionPtr FunctionPtr_) 
{
	Strike = Strike_;
	functionPtr = FunctionPtr_;
}


PayOff::PayOff(double Strike_[], arrFunctionPtr arrFunctionPtr_) 
{
	arrStrike[2] = Strike_[2];
	arrfunctionPtr = arrFunctionPtr_;
}

double PayOff::operator()(double Spot) const
{
	return functionPtr(Spot, Strike);
	// return arrfunctionPtr(Spot, arrStrike); // ??? incompatible error here
}

double call(double Spot, double Strike) 
{
	return max(Spot - Strike, 0); 
}

double doubledigital(double Spot, double Strike[2])
{
	// 1) determine which is the lower strike and higher strike
	// 2) calculate the payoff
	
	// 1)
	double *strikePtr;
	double upperStrike, lowerStrike;
	
	// and so here Strike[i] refers to ith element in Strike array
	if(Strike[0] > Strike[1])
	{
		upperStrike = Strike[0];
		lowerStrike = Strike[1];
	}
	else if(Strike[0] < Strike[1])
	{
		upperStrike = Strike[1];
		lowerStrike = Strike[0];
	}
	else
		throw("strikes can't be of equal value");
	
	// 2)
	if ((Spot > upperStrike) || (Spot < lowerStrike))
		return 0;
	else 
		return 1;
} 


Main
1
2
3
4
5
double Strike;
double arrStrike[2];

PayOff callPayOff(Strike, call);
PayOff doubledigitalPayOff(arrStrike, doubledigital);
just rephrasing the question in case it helps, how do you implement multiple overloading of the same operator in this case?

i looked up a few examples of multiple operator overloading and it seems that it works in the same way that functions are distinguished from each other by the inputs they received.
eg. operator() (int x) {} is recognised as a different overload to operator() (double x) {}, so () is overloaded in 2 ways.

however in this case, the input remains the same with double Spot, but we want a different output / different function pointer to be used depending on which constructor was used. how do you achieve this?
There is no way to distinguish either type. If the calling code knows which type is calling the operator() on, you can add a distinguishing parameter (e.g. bool type). If not, you can use a member variable to flag the type (again, e.g.: bool type).

Anyway, I'm quite worried about the fact that you have 4 members, but will only be using 2 at a time (either the 2 array members, or the 2 non-array members). It doesn't seem like they have anything in common, so why are they in the same class?
Ah ok, so is there a function or keyword that detects which constructor is being used so I can apply the distinguishing parameter? (I'm a complete newbie)

The script is more for an exercise from a textbook. The better way to do this would be via parent-child classes and virtual functions but that's the point that the author wanted to demonstrate, that function pointers can only do so much.

That said, the author said it could be done and I really want to appreciate just how much more convoluted it is to get it to work via a function pointer structure. I'd be happy if I can just get it to compile and spit out an output.

The 2 array members are an addition to the 2 non-array members in an attempt to have a second constructor which can take an array argument. Which then brings me back to trying to figure out how the overloaded operator () works ...
An operator overload means the same name with different parameters (or const-ness.) E.g.
1
2
3
4
5
6
7
class C {
 public:
    double& operator[](int index); //returns a reference of a double. Only function with this name, fine!
    double operator[](int index) const; //returns a copy to a double. Declared for const objects only, fine!
    int operator[](double value); //this one has a different parameter type, fine!
    bool operator[](int index, double value); //this one has a different parameter list length, fine!
};

That's about it. If you want one functions to act differently based on the state (or instance variables) alone, you just do stuff with those values; but you don't declare more methods. E.g.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class C {
 private:
    bool b;
 public:
    C(int x) : b(x == 1) {}
    void do_it();
};

void C::do_it() const {
    if(b)
        do_something(); //not defined
    else
        do_something_else(); //not defined
}
thanks, I think that helps, if at least for my general understanding. I'm still stuck with the code below. I'm getting an incompatible error in the operator() definition for arrStrike - although I'm not sure if I'm applying the bool indicator correctly.

Header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class PayOff
{
public:
       
       typedef double (*FunctionPtr) (double, double);
       typedef double (*arrFunctionPtr) (double, double[]);
       
       PayOff(double Strike_, FunctionPtr FunctionPtr_):ind(true){}
       PayOff(double Strike_[], arrFunctionPtr arrFunctionPtr_):ind(false){}
       double operator()(double Spot) const;
 
private:
       bool ind;
       
       double Strike;
       double arrStrike[2];
       // declaration of Strike as an array of size 2
       FunctionPtr functionPtr;
       arrFunctionPtr arrfunctionPtr;
 
};
 
double call(double Spot, double Strike); 
double doubledigital(double Spot, double Strike[2]);


Source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
PayOff::PayOff(double Strike_, FunctionPtr FunctionPtr_) 
{
       ind = true;
       Strike = Strike_;
       functionPtr = FunctionPtr_;
}
 
 
PayOff::PayOff(double Strike_[], arrFunctionPtr arrFunctionPtr_) 
{
       ind = false;
       arrStrike[2] = Strike_[2];
       arrfunctionPtr = arrFunctionPtr_;
}
 
double PayOff::operator()(double Spot) const
       
{
       if (ind == true)
              return functionPtr(Spot, Strike);
       else
              return arrfunctionPtr(Spot, arrStrike);
       
}
 
double call(double Spot, double Strike) 
       // here Strike refers to Strike[0]
{
       return max(Spot - Strike, 0); 
}
 
double doubledigital(double Spot, double Strike[2])
{
       // 1) determine which is the lower strike and higher strike
       // 2) calculate the payoff
       
       // 1)
       double *strikePtr;
       double upperStrike, lowerStrike;
       
       // and so here Strike[i] refers to ith element in Strike array
       if(Strike[0] > Strike[1])
       {
              upperStrike = Strike[0];
              lowerStrike = Strike[1];
       }
       else if(Strike[0] < Strike[1])
       {
              upperStrike = Strike[1];
              lowerStrike = Strike[0];
       }
       else
              throw("strikes can't be of equal value");
       
       // 2)
       if ((Spot > upperStrike) || (Spot < lowerStrike))
              return 0;
       else 
              return 1;
} 
Topic archived. No new replies allowed.