I am using the Eigen linear algebra library. I struggling trying to allocate Eigen Vectors in the constructor in a class, and then calling the elements of those vectors.
For example,
#include <Eigen/Dense>
using Eigen::VectorXd;
#include <memory>
using std::unique_ptr;
class Cl
{
public:
unique_ptr<VectorXd> v;
Cl(const int n);
~Cl(void);
}
Cl::Cl(const int n)
{
auto v= unique_ptr<VectorXd>(new VectorXd(n));
}
Cl::~Cl(void)
{
v= nullptr;
}
main(void)
{
Cl cl(10);
/* call an element of v how? */
}
For example, using "cl.v(2)" gives me the compiler error (I am using clang++)
error: type 'unique_ptr<VectorXd>' (aka 'unique_ptr<Matrix<double, Dynamic, 1> >') does
not provide a call operator
while using "cl.(*v)(2)" gives me
error: expected unqualified-id
cout << cl.(*v)(2) << endl;
I am new to c++, so I may be missing something very basic here.
Why are you trying to dynamically allocate the Eigen::VectorXd v; itself? Unless you would like to extend the lifetime of v beyond the lifetime of cl (in which case you would indeed have to do so), I would recommend to follow the following simple example:
#include <Eigen/Dense>
using Eigen::VectorXd;
class Cl
{
public:
VectorXd v;
Cl(int n) : v(n) {}
~Cl() {}
}
int main()
{
Cl cl(10);
for (int i=0; i<10; ++i)
cl.v(i) = i;
}
I believe in addition to the answers already regarding std::vector you are also misusing your 'unique_ptr', if indeed you actually require the use of one (reference ggael answer). Please see below example on the use of unique_ptr:
#include <iostream>
#include <memory>
#include <vector>
class Cl {
public:
std::unique_ptr<std::vector<int>> v;
Cl(const int size, int default_values);
~Cl(void);
int Size();
};
Cl::Cl(const int size, int default_values = 0) {
v.reset(new std::vector<int>(size, default_values));
}
Cl::~Cl(void) {
// do not require to reset/destroy an auto_ptr so this can be ommitted
}
int Cl::Size() {
return v->size();
}
int main(int argc, char* argv[]) {
Cl blob(10);
int size = blob.Size();
std::cout << size << std::endl;
}
In your provided code you're declaring a new auto in the constructor rather than using the variable you've defined in your Public class definition. I've included a 'Size' method so you can see the scope extends beyond the constructor.
Related
Say I get an int from a lambda function ran at initialization of a class object. Is it possible to use that int to define the size of a std::array? Something like the following code.
#include <array>
#include <vector>
#include <iostream>
class Test1 {
public:
Test1( std::vector<int> vec1 ) :
nvars([&vec1]() -> int { return vec1.size()+1; }())
{
};
const int nvars;
// ******This isn't allowed!!!!!!!!!
const std::array<int,nvars> arr;
};
int main() {
std::vector<int> vec{1,2,3,4};
Test1 test1(vec);
std::cout << "nvars: " << test1.nvars << std::endl;
return 0;
}
I am a C++ beginner so any other advice will be welcome.
No. The size of the array is part of its type. You cannot let it be determined at runtime.
You can have it be determined at compile time, if you do pass a std::array to the constructor. Since C++17 there is CTAD (class template argument deduction) which lets you write:
#include <array>
template <size_t N>
class Test1 {
public:
Test1( std::array<int,N> vec1 ) :
arr(vec1)
{
};
const std::array<int,N> arr;
};
int main() {
std::array vec{1,2,3,4};
Test1 test1(vec);
}
Live Demo
test1 is of type Test1<4>. Note that Test1<4> is a distinct different type than eg Test<5> or Test<24>. If you want one type to have a member array of different size, make it a std::vector.
I need to copy the contents of a std::list into an array, wherein the array is struct of array. Below is the code implementation of it.
#include <iostream>
#include <string>
using namespace std;
typedef struct
{
int height;
int width;
int length;
}dimensions;
GetDimensions(list<std::string>, *int); // Function that copies the content of list to array passed as second parameter
int main()
{
dimensions cuboid[10];
int plane[10];
list<std::string> planeList = GetList();//Function that returns list of elements
list<std::string> dimensionList = GetList();
GetDimensions(planeList,&plane);//This is fine, as it is a simple array
GetDimensions(dimensionList,&cuboid.height);//Trouble in implementation of this usecase, for cuboid.height, cuboid.width and cuboid.height.
return 0;
}
GetDimensions(list<std::string>dimensionList, int* dimensionParams)
{
int i=0;
for(list<std::string>::iterator it = dimensionList.begin(); it != dimensionList.end(); ++it)
{
dimensionParams[i] = stoi(*it);
i++;
}
}
Here, I need GetDimensions() function to copy the list (passed as first parameter) to array (second parameter). The implemented function works well for simple array plane. But how to pass the array of struct as parameter to the function ?
I will be getting the std::list as cuboid.height, cuboid.width and cuboid.length. So the function has to copy the contents of list from cuboid[0].height to cuboid[i].height respectively. Is there any specific function to copy the content directly?
Use std::array 's instead. Then your problem can be reduced to passing two different types of arrays to a single function.
This can be solved
either by good old function overloads
or in c++17 function template with
if-constexpr.
Following is an example code with templated function with if-constexpr (See live online)
#include <iostream>
#include <string>
#include <list>
#include <array>
#include <type_traits> // std::is_same_v
struct dimensions // no need to typedef here
{
int height;
int width;
int length;
};
template<typename T>
void GetDimensions(const list<std::string>& dimensionList, T& dimensionParams)
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //---> pass list by const-ref as the values are non-modifying
{
int i{0};
if constexpr (std::is_same_v<std::array<int, 10>, T>)
{
for(const std::string& str: dimensionList) dimensionParams[i++] = std::stoi(str);
}
else
{
for(const std::string& str: dimensionList) dimensionParams[i++].height = std::stoi(str);
}
}
int main()
{
std::array<dimensions, 10> cuboid; // use std::array instead of VLA
std::array<int, 10> plane;
std::list<std::string> planeList{"1", "2"}; // some list
std::list<std::string> dimensionList{"1", "2"};
GetDimensions(planeList, plane);
GetDimensions(dimensionList, cuboid);
return 0;
}
Also note that:
You have not specified the return type of GetDimensions function.
You probably want to return void there.
in C++ you do not need to use typedef alias for struct { ... }.
last but not least, do not practice with using namespace std;
You can do this with boost::transform_iterator.
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <boost/iterator/transform_iterator.hpp>
struct dimensions {
int height;
int width;
int length;
};
template <typename OutputIt>
void GetDimensions(std::list<std::string> dimensionList, OutputIt dimensionParams)
{
// N.b. taking the address of a standard library function is undefined, so wrap in a lambda
auto stoi = [](std::string s){ return std::stoi(s); };
std::copy(boost::make_transform_iterator(dimensionList.begin(), stoi),
boost::make_transform_iterator(dimensionList.end(), stoi),
dimensionParams);
}
int main() {
dimensions cuboid[10];
int plane[10];
std::list<std::string> planeList = GetList();
std::list<std::string> heightList = GetList();
std::list<std::string> widthList = GetList();
std::list<std::string> lengthList = GetList();
GetDimensions(planeList, plane);
GetDimensions(heightList,
boost::make_transform_iterator(cuboid, std::mem_fn(&dimensions::height)));
GetDimensions(widthList,
boost::make_transform_iterator(cuboid, std::mem_fn(&dimensions::width)));
GetDimensions(lengthList,
boost::make_transform_iterator(cuboid, std::mem_fn(&dimensions::length)));
return 0;
}
I have to use a struct array called Robot_parts[] for each part_rect struct (part_num, part_name, part_quantity, part_cost)
And through the void display function, I have to display Robot_parts[] array entirely through pointer but I don't know how, and I don't know where to declare Robot_parts[] and whether i have to put any number value inside the brackets.
So far I have:
#include <iostream>
#include <string>
using namespace std;
void display();
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
int main()
{
part_rec Robot_parts[ ] = {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
return 0;
}
void display()
{
cout<<Robot_parts[]<<endl<<endl;
}
If I also made a few other errors, please let me know. Thanks!
As stated in a comment it would be much better to use a c++ container like a std::vector or std::array.
But since your professor requires an old-style array, you could try like the code below - see the comments for explanation:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
// You have to pass a pointer (to the array) and the size of the array
// to the display function
void display(part_rec* Robot_parts, int n);
// Make a function so that you can "cout" your class directly using <<
// Note: Thanks to #BaumMitAugen who provided this comment and link:
// It makes use of the so called Operator Overloading - see:
// https://stackoverflow.com/questions/4421706/operator-overloading
// The link is also below the code section
std::ostream &operator<<(std::ostream &os, part_rec const &m)
{
// Note - Only two members printed here - just add the rest your self
return os << m.part_num << " " << m.part_name;
}
int main()
{
part_rec Robot_parts[] {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
display(Robot_parts, 3);
return 0;
}
void display(part_rec* Robot_parts, int n)
{
// Loop over all instances of your class in the array
for (int i = 0; i < n; ++i)
{
// Print your class
cout << Robot_parts[i] << endl;
}
}
The link recommended by #BaumMitAugen:
Operator overloading
enter image description hereI am trying out some STL programs. I have declared a vector in main and tried to run the program it is working but if i declare the same(vector) inside the class then am getting a compilation error. I think compiler is not recognizing vector(declared inside the class).
I have tried with std:: also still same error. I am using netbeans IDE and cigwin compiler.
please find the code below
#include <cstdlib>
#include <iostream>
#include <vector>
#include <cctype>
using namespace std;
/*
*
*/
class vectorcl
{
vector<int> v(10);
int i;
public:
vectorcl();
void add_vector();
void dis_vector();
};
vectorcl :: vectorcl()
{
for(i =0;i<10 ;i++)
{
v[i] = 0;
}
}
void vectorcl :: dis_vector()
{
cout<< " The vale is : \n";
for(i =0;i<10 ;i++)
{
cout << "\t " <<v[i];
}
}
void vectorcl :: add_vector()
{
for (i =0 ; i<10; i++)
{
v[i] = i+1;
}
}
int main(int argc, char** argv) {
// vector<int> vp(10);
// for(int j =0;j<10 ;j++)
// {
// cout << " " << vp[j];
// }
vectorcl v1;
v1.dis_vector();
v1.add_vector();
v1.dis_vector();
return 0;
}
Please help me in this, my question is why my compiler is not recognizing vector declared inside a class.
error : expected identifier before numeric constant
expected ',' or '...'before numeric constant
Error
You can not use vector<int> v(10); as member variable. The solution is to replace it by vector<int> v; and add this alter the constructor like this:
vectorcl::vectorcl():
v(std::vector<int>(10,0/* This 0 is instead of the for-loop*/)){
}
Or another option is to declare it as :
std::vector<int> v = std::vector<int>(10);
P.S. there is no need to declare int i as class member. Just declare it in every function you need.
From first glance, you are trying to call the constructor in the class prototype: vector<int> v(10);. Your constructor for that class will be called in your wrapper class constructor unless you use a member initialization list.
Edit: using member initialization
vectorcl :: vectorcl(): v(10)
{
}
I have to make a class that will make arrays act like vectors. When I try and pass the class into the method into my main I get an error telling me that "[" and "]" are incorrect operators. I was wondering if I'm just completely doing this wrong or if it's just a simple mistake. Help is greatly appreciated. Here is my header file:
#ifndef PROGRAM5HEADER_H
#ifndef PROGRAM5HEADER_H
#define PROGRAM5HEADER_H
#include <string>
using namespace std;
class FloatArray
{
int *rep;
int _size;
public:
FloatArray(int sz=100):_size(sz)
{
rep=new int[sz];
}
~FloatArray()
{
delete [] rep;
}
int size() const
{
return _size;
}
FloatArray(const FloatArray& x)
{
copy(x);
}
void copy(const FloatArray& x)
{
_size == x.size();
rep=new int[_size];
for(int k=0;k<_size;k++)
rep[k]=x.rep[k];
}
};
#endif
and here is my main program
#include <iostream>
#include <string>
#include <cstdlib>
#include "program5header.h"
#include <cmath>
using namespace std;
int meanstd(FloatArray x, int& std)
{
int sx=0,sx2=0,mean;
for(int i=0;i<x.size();i++)
{
sx+=x[i];
sx2+=x[i]*x[i];
}
mean=sx/x.size();
std=sqrt(sx2/x.size()-mean*mean);
return mean;
}
int main()
{ int f;
cout<<"How big of an array would you like: "<<endl;
cin>>f;
FloatArray x(f);
}
There are a lot of issues with a lot of your implementation, I'd suggest doing some research on the subject. I'll touch on a few.
Firstly, you should make your FloatArray a templated class and allow for different types other than just int.
When you initialize a FloatArray x and then try to access it's underlying array through "[]" you are actually invoking the following:
x.operator[](...)
You haven't defined the '[]' operator on your FloatArray class so you are getting an error.
You need something similar to this:
int FloatArray.operator[](int index) {
assert(index < _size);
return _rep[index]
}
Your copy isn't doing what you want, it's not copying the size over to "this". It should look something similar to this:
void copy(const FloatArray& x)
{
_size = x._size;
rep=new int[_size];
for(int k=0;k<_size;k++)
rep[k]=x.rep[k];
}
However I would suggest not having a copy method and instead implement everything in your copy constructor.