iteong
iteong

Reputation: 735

error: request for member ‘end’ in .... which is of non-class type ‘double’

I got the following error which I suspect has something to do with the mismatch of types or something.... The magnitude_ variable that is used in the function is a double array declared as a pointer (e.g. double *magnitude_;) and in the function I'm trying to get the begin and end of the double array, but it doesn't seem to work.. I also tried

for (auto iter = std::begin(magnitude_); iter != std::end(magnitude_); ++iter)

but it doesn't seem to work. Can anyone advise me on this?:

EuclideanVector.cpp: In member function ‘void evec::EuclideanVector::updateNormal()’:
EuclideanVector.cpp:180:32: error: request for member ‘begin’ in ‘*((evec::EuclideanVector*)this)->evec::EuclideanVector::magnitude_’, which is of non-class type ‘double’
   for (auto iter = magnitude_->begin(); iter != magnitude_->end(); ++iter)
                                ^~~~~
EuclideanVector.cpp:180:61: error: request for member ‘end’ in ‘*((evec::EuclideanVector*)this)->evec::EuclideanVector::magnitude_’, which is of non-class type ‘double’
   for (auto iter = magnitude_->begin(); iter != magnitude_->end(); ++iter)

The function in the .cpp file is:

void EuclideanVector::updateNormal()
    {
        double normal_tmp = 0.0;

        for (auto iter = magnitude_->begin(); iter != magnitude_->end(); ++iter)
        {
            normal_tmp += pow(*iter, 2);
        }

        *normal_ =  sqrt(normal_tmp);

    }

Upvotes: 2

Views: 2002

Answers (6)

Xirema
Xirema

Reputation: 20396

Consider the following:

double * ptr = new double[5];
auto iter = std::end(ptr); //uhh.....

What, exactly, are you expecting std::end to do in this context? Pointers don't store information about how many objects they're holding*, so how would std::end go about finding the end of an arbitrary pointer that's been passed to it?

std::begin and std::end can't be used with raw pointer-based arrays. Simply iterate with the pointer itself.

for(double * iter = ptr; iter < ptr+5; iter++) {
    double val = *iter;
    /*...*/
}

* - Okay, technically the compiler does store this information, but it's not accessible in a programmer/language-visible manner.

Upvotes: 0

meetaig
meetaig

Reputation: 915

The way you access your variable you assume this is something like a std::vector which has an iterator built in. But using a plain double array this obviously does not work. That's why you get the is of non-class type error. double is not a class but a data type. If you want to use iterators, use std::vector<double> or something similar. Otherwise use the traditional for loop

for(int ii = 0; ii < numel; ii++)
{
    normal_tmp += pow(magnitude_[ii], 2);
}

Upvotes: 0

sjrowlinson
sjrowlinson

Reputation: 3355

A double* variable (i.e. a pointer to a C-style array) is not a class or struct and does not have begin() nor end() iterator access functions.

You can either use pointer arithmetic requiring access to the size of the array magnitude_ like so:

for (double* it = magnitude_; it != (magnitude_ + magnitude_size); ++it)
    normal_tmp += (*iter)*(*iter);

Or change magnitude_ to a std::array<double, mag_size> or a std::vector<double> depending upon whether magnitude_ is fixed in size or needs to be expanded/contracted, and then you can use begin() and end() as you have done in the question.

Upvotes: 1

Mark B
Mark B

Reputation: 96311

Just as in C and C++ raw pointers (double*) don't contain size information, end can't extract it from a raw pointer. You probably want to use a sized C-array foo[100] or a std::array or std::vector depending on your needs.

Upvotes: 0

YamiTenshi
YamiTenshi

Reputation: 176

Your array is not a class or an object or anything, it's basically just the memory address of the first element (and as such of type double*). You're using the -> operator, which dereferences that into the double located at that memory address (which works just fine), and then tries to call the method end() on that. However, your variable isn't a class containing a method end(), it's a double. An array in C++ is nothing more than a bunch of values stored right next to each other in memory.

If you want your array to have those methods, declare it as a std::vector<double>. Otherwise, you'll have to keep track of the array's size yourself, and do something like

for (int i = 0; i < size; i++) {
    double val = magnitude_[i];
    // ....
}

Upvotes: 1

Cory Kramer
Cory Kramer

Reputation: 118021

You need to also know the size of the array (e.g. num_elements), then you can use pointer arithmetic

for (double* iter = magnitude_; iter != (magnitude_ + num_elements); ++iter)
{
    double value = *iter;
}

Or simply use indexing

for (int i = 0; i < num_elements; ++i)
{
    double value = magnitude_[i];
}

Then only way std::begin and std::end would have worked is if the array size was known in that scope, e.g.

double magnitude_[10];
for (auto iter = std::begin(magnitude_); iter != std::end(magnitude_); ++iter)
{
}

I'd suggest either switching to std::array or std::vector depending on how your array is allocated, then you can use these methods more easily.

Upvotes: 4

Related Questions