2

I'm trying to call addValues below:

Obj *s = new Obj();
vector<tm> dates(SIZE);
vector<double> values[COUNT];
for (uint i = 0; i < COUNT; i++) {
    values[i] = vector<double>(SIZE);
}
s->addValues(&dates, &values); // <- this is the error line

and I've defined addValues:

void addValues(vector<tm> *newDates, vector<double> (*newValues)[COUNT]);

The exact error is:

no matching function for call to ‘Stock::addValues(std::vector<tm, std::allocator<tm> >*, std::vector<double, std::allocator<double> > (*)[5])’

I think the idea is that my method signature does not match. What is the correct signature for addValues?

Kevin
  • 1,080
  • 3
  • 15
  • 41

2 Answers2

1
template <size_t N>
void addValues(vector<tm>* newDates, vector<double> (&newValues)[N]);

The reason this works is because its a template. The value N is known at compile time since you define values as an array: vector<double> values[COUNT]. Since the compiler knows the size of values at compile time, it is able to replace N with COUNT.

Since it is a template you will be able to call this function with any size array, not necessarily COUNT size.

I would also recommend changing newDates to a reference, as Fred Nurk suggested.

template <size_t N>
void addValues(vector<tm>& newDates, vector<double> (&newValues)[N]);
Marlon
  • 19,924
  • 12
  • 70
  • 101
  • 2
    To elaborate on why this works - this code parameterizes the function over the number of elements in the array, which allows you to accept an array of any size while preserving the size information. That way, you get two things. First, you'd pass the array of vectors by value rather than by pointer, which is a bit more sane. Second, you never need to worry about size agreement again - the compiler will record how much space is being used. – templatetypedef Feb 01 '11 at 08:03
  • @templatetypedef: If you want to pass an array ref instead of an array pointer, you can do that without this. Dimensions of array pointers are checked just as they are for array references. – Fred Nurk Feb 01 '11 at 08:10
  • @Fred Nurk- True; I didn't mean to suggest that it wasn't. What I meant here by "agreement" was that you wouldn't have to write the code to only accept one size and then worry about using that particular size everywhere. – templatetypedef Feb 01 '11 at 08:14
  • I was under the impression that passing by pointer and by "&" were semantically the same. Is that correct? This worked for me though. Does anyone have a link to a good explanation? – Kevin Feb 01 '11 at 08:17
  • * is pointer, & is reference. In C++, most of the time we use references since we are "referring" to an actual object, not necessarily a block of memory. Not sure if that made sense. – Marlon Feb 01 '11 at 08:27
  • Here's a good topic about [pointers and references](http://stackoverflow.com/questions/57483/difference-between-pointer-variable-and-reference-variable-in-c) – Marlon Feb 01 '11 at 08:35
1

This is how I rewrote your code to make it compile:

#include <ctime>
#include <vector>

using namespace std;

typedef unsigned int uint;

#define SIZE 3
#define COUNT 3

struct Obj {
    void addValues(vector<tm> *newDates, vector<double> (*newValues)[COUNT])
    {}
};

int main() {
    Obj *s = new Obj();
    vector<tm> dates(SIZE);
    vector<double> values[COUNT];
    for (uint i = 0; i < COUNT; i++) {
        values[i] = vector<double>(SIZE);
    }
    s->addValues(&dates, &values); 
}

and it compiles correctly.

As you see, the code is almost the same as yours. Try checking if the COUNT value used in the member function's declaration is the same as the one where you create values.

Simone
  • 11,655
  • 1
  • 30
  • 43