I am trying to calculate the lpNorm of a vector with the Eigen library.
As it can be seen in the example below, with explicit values, such as v.lpNorm<1>(), it works. But it doesn't work inside the loop, with lpNorm<p>()
How can I fix this?
#include <iostream>
#include <Eigen/Dense>
using Eigen::VectorXd;
int main()
{
int sizev = 3;
int p;
Eigen::VectorXd v(sizev);
v(0) = 3.;
v(1) = 2.;
v(2) = 1.;
// test 1, passes
std::cout << "||v||_" << 1 << " = " << v.lpNorm<1>() << std::endl;
std::cout << "||v||_" << 2 << " = " << v.lpNorm<2>() << std::endl;
std::cout << "||v||_" << 3 << " = " << v.lpNorm<3>() << std::endl;
std::cout << "||v||_" << 4 << " = " << v.lpNorm<4>() << std::endl;
std::cout << "||v||_inf = " << v.lpNorm<Eigen::Infinity>() << std::endl;
// test 2, fails
for (int p=1; p<5; p++)
{
std::cout << "||v||_" << p << " = " << v.lpNorm<p>() << std::endl;
}
return 0;
}
On compilation, I am getting the error
error: no matching member function for call to 'lpNorm'
std::cout << "||v||_" << p << " = " << v.lpNorm<p>() << std::endl;
~~^~~~~~~~~
note: candidate template ignored: invalid explicitly-specified argument for template parameter 'p'
template<int p> EIGEN_DEVICE_FUNC RealScalar lpNorm() const;
^
1 error generated.
You cannot use variable integer as a template argument, it needs to be a compile time constant, such as
constexpr int p = 3;
v.lpNorm<p>();
However, you can still have a kind of compile-time loop using e.g. std::integer_sequence. I modified a bit the example from documentation to call a function:
template<typename T, T... ints>
void exec_constexpr_loop(std::integer_sequence<T, ints...> int_seq, Eigen::Ref<Eigen::VectorXd> v)
{
((v.lpNorm<ints>()), ...);
}
exec_constexpr_loop(std::integer_sequence<int, 1, 2, 3>{}, v);
Live demo with dummy function, works since C++17.
Related
I am not sure how to explain this behaviour, displayed here with a minimal example.
Why isn't size correctly captured ?
#include <iostream>
#include <vector>
using namespace std;
auto&& matcher1KO = [] (vector<int> &v){
int size = v.size();
cout << "size outside : " << size << "\n"; // print 1
return [&] (bool b) {
cout << "v.size() : " << v.size() << "\n"; // print 1
cout << "size inside : " << size << "\n"; // print 0
};
};
auto&& matcher2OK = [] (vector<int> &v){
int size = v.size();
cout << "size outside : " << size << "\n"; // print 1
return [&] () {
cout << "v.size() : " << v.size() << "\n"; // print 1
cout << "size inside : " << size << "\n"; // print 1
};
};
int main() {
vector<int> v {+1};
auto matcherf1 = matcher1KO(v); //
matcherf1(true);
auto matcherf2 = matcher2OK(v);
matcherf2();
}
Both the code have undefined behavior, anything is possible.
The reason is the same for the two cases: the variable size is a local object inside the operator() of the lambda, it will be destroyed when the invocation ends. You're capturing size by-reference and the reference is dangled.
Changing it to capture-by-value would be fine. e.g.
return [=] (bool b) {
cout << "v.size() : " << v.size() << "\n"; // print 1
cout << "size inside : " << size << "\n"; // print 1
};
I'm trying to use displayVectorVer2() to have it only display the first 10 elements, but I don't know how to do it with iterators. I did try a few dumb things just to see what would happen: I compared the iterator to displayLimit in my for loop. I played around by subtracting vobj.end()-5 since my professor is only having me use 15 elements, but I fully well knew this was not a good idea.
#include <iostream>
#include <vector>
#include <ctime>
template <class T>
void fillVector(std::vector<T>& vobj, int n);
template <class T>
void displayVectorVer2(std::vector<T>& vobj, typename std::vector<T>::iterator ptr);
template <class T>
void fillVector(std::vector<T>& vobj, int n)
{
srand((unsigned int)time(NULL));
for (int i=0; i<n; ++i)
{
vobj.push_back(rand()%99999+1);
}
}
template <class T>
void displayVectorVer2(std::vector<T>& vobj, typename std::vector<T>::iterator ptr)
{
std::cout << "Vector object contains " << vobj.size() << " values which are" << std::endl;
const unsigned displayLimit = 10;
if (vobj.size()>displayLimit)
{
for (ptr=vobj.begin(); ptr<vobj.end(); ++ptr)
{
std::cout << " " << *ptr;
}
std::cout << " ..." << std::endl;
}
else
{
for (ptr=vobj.begin(); ptr<vobj.end(); ++ptr)
{
std::cout << " " << *ptr;
}
std::cout << std::endl;
}
}
int main()
{
std::vector<int> vobj;
std::cout << "Before calling fillVector(...): vobj contains "
<< vobj.size() << " values." << std::endl;
std::cout << "\nEnter # of random values you'd like to store in vobj: ";
int n;
std::cin >> n;
std::cout << "\n*** Calling fillVector(...) ***" << std::endl;
fillVector(vobj, n);
std::cout << "\n*** Calling displayVectorVer2(...) ***" << std::endl;
std::vector<int>::iterator ptr;
displayVectorVer2(vobj,ptr);
}
Maybe I am thinking too simple but, that wold solve your question:
I'm trying to use displayVectorVer2() to have it only display the
first 10 elements
without knowing your full exercise, that would be my answer:
...
const unsigned displayLimit = 10;
if (vobj.size()>displayLimit)
{
for (ptr=vobj.begin(); ptr<vobj.begin()+displayLimit; ++ptr)
{
std::cout << " " << *ptr;
}
std::cout << " ..." << std::endl;
}
else
...
edit:
That worked, but why does it work? I remember adding to vobj.begin() and getting extra empty elements appended to the original vector.
Not sure what exactly you did but maybe that helps you understanding your code:
...
const unsigned displayLimit = 10;
if (vobj.size()>displayLimit)
{
//Init ptr outside the for loop
ptr = vobj.begin();
//What the for loop is seeing with a more familiar syntax:
//for( ; i < 0 +displayLimit; ++i)
//what you are seeing
for (/*ptr init*/; ptr < vobj.begin() +displayLimit; ++ptr)
{
std::cout << " " << *ptr;
}
std::cout << " ..." << std::endl;
}
...
The iterators just gives you the int value and you can use it with what ever "eats" int values. In your case the for loop.
If you tell the program to use an iterator you tell the program: "Just give me the number the Vector begins with and add 10".
In your case 0 "...and add 10"
You could also write a code like that with n passed to the function
for being able to use .end - input + 10 for showing 10 lines:
...
template <class T>
void displayVectorVer2(std::vector<T>& vobj, typename std::vector<T>::iterator ptr,int n)
{
std::cout << "Vector object contains " << vobj.size() << " values which are" << std::endl;
const unsigned displayLimit = 10;
if (vobj.size()>displayLimit)
{
ptr=vobj.begin();
for (; ptr<vobj.end() -n +displayLimit; ++ptr)
{
std::cout << " " << *ptr;
}
std::cout << " ..." << std::endl;
}
else
{
for (ptr=vobj.begin(); ptr<vobj.end(); ++ptr)
{
std::cout << " " << *ptr;
}
std::cout << std::endl;
}
}
int main()
{
std::vector<int> vobj;
std::cout << "Before calling fillVector(...): vobj contains "
<< vobj.size() << " values." << std::endl;
std::cout << "\nEnter # of random values you'd like to store in vobj: ";
int n;
std::cin >> n;
std::cout << "\n*** Calling fillVector(...) ***" << std::endl;
fillVector(vobj, n);
std::cout << "\n*** Calling displayVectorVer2(...) ***" << std::endl;
std::vector<int>::iterator ptr;
displayVectorVer2(vobj,ptr,n);
}
...
You also shouldn't use srand in modern code anymore since it is depricated for more than 10 years since c++11 introduced <random>
and srand can harm your program f.e. if used for generating seeds for sensitive code. Also srand provides not the "randomness" it should provide, srand generates some numbers more often than others - that's not random.
I have a class that I use with the Armadillo package to create a specific kind of matrix. I'm having trouble debugging it, so I would like to use a function I have written called Matlab_Print. It lives in its own .h and .cpp file and is used throughout my code. The class and the function both work perfectly, but I do not seem to be able to combine them.
I have tried #include "Matlab_Print" in SU3.h both before and after the class definition. I really don't want to make the function a class function as I use Matlab_Print frequently. I do have a workaround but it is inconvenient, and at any rate I am looking at this as a learning opportunity.
I trap error messages with a try when calling the SU3 constructor and I get the following:
error: Mat::init(): size is fixed and hence cannot be changed
main.cpp
#include "pch.h"
#include <new>
#include <exception>
#include "SU3.h"
int main(int argc, char *argv[])
{
int icount { 0 };
SU3 *su3[10];
try
{
for (icount = 0; icount < 10; icount++)
{
su3[icount] = new SU3(0.1);
}
}
catch (int param) { cout << "Function " << __func__ << " int " << param << " exception in memory allocation for su3" << std::endl; exit(1); }
catch (char param) { cout << "Function " << __func__ << " char " << param << " exception in memory allocation for su3" << std::endl; exit(1); }
catch (...) { cout << "Function " << __func__ << " exception in memory allocation for su3" << std::endl; exit(1); }
return 0;
}
SU3.h
#include "pch.h"
#include "SU3.h"
#include <armadillo>
#include "Matlab_Print.h"
class SU3
{
public:
arma::Mat<cx_double>::fixed<3, 3> *X;
SU3(const double epsilon);
};
SU3.cpp
SU3::SU3(const double epsilon) // simplifed so that epsilon plays no role
{
const std::complex<double> o{ 1.0 , 0.0 }; // complex 1
const std::complex<double> z{ 0.0 , 1.0 }; // complex 0
X = new arma::Mat<cx_double>::fixed<3, 3>{ fill::zeros }; //// solution to problem: define and initialize pointer ////
*X = { { o, z, z},
{ z, o, z},
{ z, z, o} };
Matlab_Print(*X, "SU3"); // this is the line I wish to use
}
Matlab_Print.h
#include <armadillo>
#include <complex>
void Matlab_Print(arma::Mat<cx_double>::fixed<3, 3> Matrix, std::string T);
Matlab_Print.cpp
#include "pch.h"
#include "Matlab_Print.h"
void Matlab_Print(arma::Mat<cx_double>::fixed<3, 3> Matrix, std::string T)
{
std::cout << std::endl;
std::cout << "RE = [" << std::real(Matrix(0, 0)) << " " << std::real(Matrix(0, 1)) << " " << std::real(Matrix(0, 2)) << "; ";
std::cout << std::real(Matrix(1, 0)) << " " << std::real(Matrix(1, 1)) << " " << std::real(Matrix(1, 2)) << "; ";
std::cout << std::real(Matrix(2, 0)) << " " << std::real(Matrix(2, 1)) << " " << std::real(Matrix(2, 2)) << "]; " << std::endl;
std::cout << "IM = [" << std::imag(Matrix(0, 0)) << " " << std::imag(Matrix(0, 1)) << " " << std::imag(Matrix(0, 2)) << "; ";
std::cout << std::imag(Matrix(1, 0)) << " " << std::imag(Matrix(1, 1)) << " " << std::imag(Matrix(1, 2)) << "; ";
std::cout << std::imag(Matrix(2, 0)) << " " << std::imag(Matrix(2, 1)) << " " << std::imag(Matrix(2, 2)) << "]; " << std::endl;
std::cout << T << " = RE + 1i*IM;" << std::endl;
}
Thank you for your patience. I hope this is all of the information you need.
As #uneven_mark notes, you have undefined behavior in SU3::SU3, because you are dereferencing X without initializing it first. You probably don't want a pointer here.
N.b. you don't need new to create objects of class type.
class SU3
{
public:
arma::Mat<cx_double>::fixed<3, 3> X;
SU3(const double epsilon);
};
using namespace std::literals::complex_literals;
SU3::SU3(const double epsilon)
: X({ { 1, 1i, 1i },
{ 1i, 1, 1i },
{ 1i, 1i, 1 } }) // prefer member initialisers over assingments
{
Matlab_Print(X, "SU3");
}
I have a POD class and I want to make it movable for efficiency. I keep all the data in a std::array member object, and I make my public member variables references to parts of this std::array object. By doing this, now I am able to move the entire data by moving the std::array instance in the move constructor (I know that it is not literally a POD class anymore after writing constructors.).
Is this a good method of doing this? Does it actually move the data? See the code output below: After moving the std::array, I observe that both objects have the same values. It looks like it doesn't move, but it copies the data. What is the problem here?
#include <array>
class MyPodClass
{
private:
typedef double TYPE_x;
typedef double TYPE_y;
typedef double TYPE_z;
typedef int TYPE_p;
typedef int TYPE_r;
typedef int TYPE_s;
typedef char TYPE_k;
typedef char TYPE_l;
typedef char TYPE_m;
typedef float TYPE_a;
typedef float TYPE_b;
typedef float TYPE_c;
enum TypeSizes
{
STARTING_POSITION_x = 0,
STARTING_POSITION_y = STARTING_POSITION_x + sizeof(TYPE_x),
STARTING_POSITION_z = STARTING_POSITION_y + sizeof(TYPE_y),
STARTING_POSITION_p = STARTING_POSITION_z + sizeof(TYPE_z),
STARTING_POSITION_r = STARTING_POSITION_p + sizeof(TYPE_p),
STARTING_POSITION_s = STARTING_POSITION_r + sizeof(TYPE_r),
STARTING_POSITION_k = STARTING_POSITION_s + sizeof(TYPE_s),
STARTING_POSITION_l = STARTING_POSITION_k + sizeof(TYPE_k),
STARTING_POSITION_m = STARTING_POSITION_l + sizeof(TYPE_l),
STARTING_POSITION_a = STARTING_POSITION_m + sizeof(TYPE_m),
STARTING_POSITION_b = STARTING_POSITION_a + sizeof(TYPE_a),
STARTING_POSITION_c = STARTING_POSITION_b + sizeof(TYPE_b),
END_POSITION = STARTING_POSITION_c + sizeof(TYPE_c),
};
std::array<unsigned char, END_POSITION> MovableBulkData;
public:
MyPodClass()
: //x(*static_cast<TYPE_x*>(&MovableBulkData[STARTING_POSITION_x])), // ERROR: Invalid type conversion. Why?
x(*(TYPE_x*)(&MovableBulkData[STARTING_POSITION_x])),
y(*(TYPE_y*)(&MovableBulkData[STARTING_POSITION_y])),
z(*(TYPE_z*)(&MovableBulkData[STARTING_POSITION_z])),
p(*(TYPE_p*)(&MovableBulkData[STARTING_POSITION_p])),
r(*(TYPE_r*)(&MovableBulkData[STARTING_POSITION_r])),
s(*(TYPE_s*)(&MovableBulkData[STARTING_POSITION_s])),
k(*(TYPE_k*)(&MovableBulkData[STARTING_POSITION_k])),
l(*(TYPE_l*)(&MovableBulkData[STARTING_POSITION_l])),
m(*(TYPE_m*)(&MovableBulkData[STARTING_POSITION_m])),
a(*(TYPE_a*)(&MovableBulkData[STARTING_POSITION_a])),
b(*(TYPE_b*)(&MovableBulkData[STARTING_POSITION_b])),
c(*(TYPE_c*)(&MovableBulkData[STARTING_POSITION_c]))
{
}
MyPodClass(MyPodClass && RValue)
: MovableBulkData(std::move(RValue.MovableBulkData)),
x(*(TYPE_x*)(&MovableBulkData[STARTING_POSITION_x])),
y(*(TYPE_y*)(&MovableBulkData[STARTING_POSITION_y])),
z(*(TYPE_z*)(&MovableBulkData[STARTING_POSITION_z])),
p(*(TYPE_p*)(&MovableBulkData[STARTING_POSITION_p])),
r(*(TYPE_r*)(&MovableBulkData[STARTING_POSITION_r])),
s(*(TYPE_s*)(&MovableBulkData[STARTING_POSITION_s])),
k(*(TYPE_k*)(&MovableBulkData[STARTING_POSITION_k])),
l(*(TYPE_l*)(&MovableBulkData[STARTING_POSITION_l])),
m(*(TYPE_m*)(&MovableBulkData[STARTING_POSITION_m])),
a(*(TYPE_a*)(&MovableBulkData[STARTING_POSITION_a])),
b(*(TYPE_b*)(&MovableBulkData[STARTING_POSITION_b])),
c(*(TYPE_c*)(&MovableBulkData[STARTING_POSITION_c]))
{
}
const MyPodClass & operator=(MyPodClass && RValue)
{
MovableBulkData = std::move(RValue.MovableBulkData);
return *this;
}
TYPE_x & x;
TYPE_y & y;
TYPE_z & z;
TYPE_p & p;
TYPE_r & r;
TYPE_s & s;
TYPE_k & k;
TYPE_l & l;
TYPE_m & m;
TYPE_a & a;
TYPE_b & b;
TYPE_c & c;
};
int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
{
MyPodClass PodObject1, PodObject2;
PodObject1.y = 3.4;
PodObject1.s = 4;
PodObject1.m = 'm';
PodObject1.a = 2.3f;
std::cout << "PodObject1.y = " << PodObject1.y << std::endl;
std::cout << "PodObject1.s = " << PodObject1.s << std::endl;
std::cout << "PodObject1.m = " << PodObject1.m << std::endl;
std::cout << "PodObject1.a = " << PodObject1.a << std::endl << std::endl;
std::cout << "PodObject2.y = " << PodObject2.y << std::endl;
std::cout << "PodObject2.s = " << PodObject2.s << std::endl;
std::cout << "PodObject2.m = " << PodObject2.m << std::endl;
std::cout << "PodObject2.a = " << PodObject2.a << std::endl << std::endl;
std::cout << "Moving PodObject1 to PodObject2..." << std::endl << std::endl;
PodObject2 = std::move(PodObject1);
std::cout << "PodObject1.y = " << PodObject1.y << std::endl;
std::cout << "PodObject1.s = " << PodObject1.s << std::endl;
std::cout << "PodObject1.m = " << PodObject1.m << std::endl;
std::cout << "PodObject1.a = " << PodObject1.a << std::endl << std::endl;
std::cout << "PodObject2.y = " << PodObject2.y << std::endl;
std::cout << "PodObject2.s = " << PodObject2.s << std::endl;
std::cout << "PodObject2.m = " << PodObject2.m << std::endl;
std::cout << "PodObject2.a = " << PodObject2.a << std::endl << std::endl;
std::cout << "Modifying PodObject1 and PodObject2..." << std::endl << std::endl;
PodObject1.s = 5;
PodObject2.m = 'n';
std::cout << "PodObject1.y = " << PodObject1.y << std::endl;
std::cout << "PodObject1.s = " << PodObject1.s << std::endl;
std::cout << "PodObject1.m = " << PodObject1.m << std::endl;
std::cout << "PodObject1.a = " << PodObject1.a << std::endl << std::endl;
std::cout << "PodObject2.y = " << PodObject2.y << std::endl;
std::cout << "PodObject2.s = " << PodObject2.s << std::endl;
std::cout << "PodObject2.m = " << PodObject2.m << std::endl;
std::cout << "PodObject2.a = " << PodObject2.a << std::endl << std::endl;
std::cout << std::endl;
_wsystem(L"timeout /t 60 /nobreak");
return 0;
}
Output:
PodObject1.y = 3.4
PodObject1.s = 4
PodObject1.m = m
PodObject1.a = 2.3
PodObject2.y = -9.25596e+61
PodObject2.s = -858993460
PodObject2.m = ╠
PodObject2.a = -1.07374e+08
Moving PodObject1 to PodObject2...
PodObject1.y = 3.4
PodObject1.s = 4
PodObject1.m = m
PodObject1.a = 2.3
PodObject2.y = 3.4
PodObject2.s = 4
PodObject2.m = m
PodObject2.a = 2.3
Modifying PodObject1 and PodObject2...
PodObject1.y = 3.4
PodObject1.s = 5
PodObject1.m = m
PodObject1.a = 2.3
PodObject2.y = 3.4
PodObject2.s = 4
PodObject2.m = n
PodObject2.a = 2.3
This is a misuse of move semantics. Since your class contains a number of simple data members like int and float, there is really nothing to move. You'd be better off with memcpy(), which is probably close to what your compiler gives you for free if you just write the class the normal, naive way, with no std::array and no pointer gymnastics.
Move semantics would have been useful here if your class contained e.g. a std::string, because std::string uses dynamically allocated memory which can be "moved" (read: adopted) into the target of a move.
The above of course means that you could "fix" your problem by dynamically allocating the array, which would allow you to move it. But in the end this would be a baroque way to achieve the effect of using a trivial POD class with no gymnastics and storing it in a std::unique_ptr, which of course enables move semantics.
I have been searching on Google an in this forum for a while, but I could not find any answer or tip for my problem. Tutorials couldn't help me either...
I want to redistribute some points, stored in a vector p_org. (x-value is stored as double).
Therefore I have the function distribute, which is defined in maths.h
distribute_tanh(&p_org_temp,&p_new_temp,iz,spacing[0],spacing[1],l_rot[(kk+1)*iz-2],status);
The function distribute_tanh does look like this:
inline void distribute_tanh (std::vector<double> *p_org, std::vector<double> *p_new, const int n_points, double spacing_begin, double spacing_end, const double total_length, double status){
//if status == 0: FLAP, if status == 1: SLAT
std::cout << "spacing_begin: " << spacing_begin << " spacing_end: " << spacing_end << std::endl;
double s_begin = spacing_begin / total_length;
double s_end = spacing_end / total_length;
double A = sqrt(s_end/s_begin);
double B = 1 / (sqrt(s_end*s_begin)*n_points);
std::cout << "A: " << A << " B: " << B << std::endl;
std::vector<double> u (n_points);
std::vector<double> sn (n_points);
double dx;
double dy;
std::cout << "Control at the beginning: p_org: " << (p_org) << " p_new: " << (p_new) << " n_points: " << n_points << " s_begin: " << s_begin << " s_end: " << s_end << " total_length: " << total_length << std::endl;
//problem no. 1
for (int i=0;i<n_points;i++){
if (B > 1.001) {
if (B < 2.7829681) {
double Bq=B-1;
dy=sqrt(6*Bq)*(1-0.15*Bq+0.057321429*pow(Bq,2)-0.024907295*pow(Bq,3)+0.0077424461*pow(Bq,4)-0.0010794123*pow(Bq,5));
} else if (B > 2.7829681) {
double Bv=log(B);
double Bw=1/B-0.028527431;
dy=Bv+(1+1/Bv)*log(2*Bv)-0.02041793+0.24902722*Bw+1.9496443*pow(Bw,2)-2.6294547*pow(Bw,3)+8.56795911*pow(Bw,4);
}
u[i]=0.5+(tanh(dy*(i*(1.0/n_points)-0.5))/(2*tanh(dy/2)));
}
else if (B < 0.999) {
if (B < 0.26938972) {
dx=M_PI*(1-B+pow(B,2)-(1+(pow(M_PI,2))/6)*pow(B,3)+6.794732*pow(B,4)-13.205501*pow(B,5)+11.726095*pow(B,6));
} else if (B > 0.26938972) {
double Bq=1-B;
dx=sqrt(6*Bq)*(1+0.15*Bq+0.057321429*pow(Bq,2)+0.048774238*pow(Bq,3)-0.053337753*pow(Bq,4)+0.075845134*pow(Bq,5));
}
u[i]=0.5+(tan(dx*(i*(1.0/n_points)-0.5))/(2*tan(dx/2)));
}
else {
u[i]=i*(1.0/n_points)*(1+2*(B-1)*(i*(1.0/n_points)-0.5)*(1-i*(1.0/n_points)));
}
sn[i]=u[i]/(A+(1.0-A)*u[i]);
std::cout << "sn(i): " << sn[i] << std::endl;
std::cout << "p_org[n_points]: " << &p_org[n_points-1] << std::endl;
if(status==0){
//p_new[i]=p_org[0]+(total_length*sn[i]);
std::cout << "FLAP maths.h" << std::endl;
}
//Here is the problem no. 2
else if(status==1){
//p_new[i]=p_org[0]-(total_length*sn[i]);
std::cout << "SLAT maths.h" << std::endl;
}
//std::cout << "p_new in math: " << p_new << std::endl;
}
}
My problem is, that I am unable to access the value of p_org or p_new. At the beginning I would like to give out the value of p_org and p_new. If I try it with a *, the compiler is complaining: error: no operator "<<" matches these operands
operand types are: std::basic_ostream> << std::vector>
std::cout << "Control at the beginning: p_org: " << (*p_org) << " p_new: " << (*p_new) << " n_points: " << n_points << " s_begin: " << s_begin << " s_end: " << s_end << " total_length: " << total_length << std::endl;
If I leave the * off, I get the addresses of p_org and p_new.
At the end of the code I would like to write the new value to p_new. If I use * to access the value, the compiler is complaining, if I leave it off, its complaining too with the following message:
error: no operator "-" matches these operands
operand types are: std::vector<double, std::allocator<double>> - double
p_new[i]=p_org[0]-(total_length*sn[i]);
^
I tried to understand both problems, but until now I had no success.
Thanks for your advice.
Your issue with the compiler error can be cut down to a very simple program.
#include <vector>
void foo(std::vector<int>* pV)
{
pV[0] = 10; // error.
}
int main()
{
std::vector<int> v(10);
foo(&v);
}
The issue is that operator[] as done above works for objects and references, not pointers. Since pv is a pointer, you must dereference it first to obtain the object, and then apply [] to the dereferenced pointer.
void foo(std::vector<int>* pV)
{
(*pV)[0] = 10; // No error
}
The other form of calling operator[] can be also used, but is a bit more verbose:
void foo(std::vector<int>* pV)
{
pv->operator[](0) = 10; // No error
}
However, to alleviate having to do this, pass the vector by reference. Then the "normal" way of using operator[] can be used.
#include <vector>
void foo(std::vector<int>& pV)
{
pV[0] = 10; // No error.
}
int main()
{
std::vector<int> v(10);
foo(v);
}