I'm new to C++/CLI and are having a hard time with Lists.
I have a structure
#using namespace System::Collections::Generic
struct myStruct {
unsigned int A ;
int B; };
and i want to create a list with mystructs
List<myStruct> myList;
But that seems not to work, Visual Studio says
"myStruct is not a valid generic Argument", but why is that so?
And how can i make this structure a "valid generic argument"?
#include <List>
struct myStruct {
unsigned int A ;
int B;
};
std::list<myStruct> myList;
int main(void) {
return 0;
}
Related
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've been trying to use arrays in a class constructor. Here is my code:
struct Motor_Group{
int Motors[3];
int Encoder;
};
int main()
{
Motor_Group Left_Drive {{2,3},3};
Motor_Group Right_Drive {{2,3},3};
cout<< sizeof(Left_Drive.Motors)/sizeof(int);
return 0;
}
But, the problem is that i want to make the length of the array motors to be undefined untill its contents is declared. How can i do that?
Thanks for your kind help!
If you do not need MotorGroups to be of the same type,
then you could template the array size.
Using std::array
#include <array>
#include <iostream>
template<size_t motor_count>
struct Motor_Group{
std::array<int,motor_count> Motors;
int Encoder;
};
int main()
{
Motor_Group<2> Left_Drive {{2,3},3};
Motor_Group<3> Right_Drive {{2,3,4},3};
std::cout<< Left_Drive.size();
// Left_Drive = Right_Drive; // Error at compile time, since Motor_Group<2> != Motor_Group<3>
return 0;
}
How would I go about initializing a vector of struct instances in C++? For example, if I had:
struct node {int a; int b;};
int main() {
std::vector<node> V {node node1, node node2...};
}
How can I go about initializing the nodes in the vector in the declaration? Is this possible? I am using C++11 with initializer lists but am confused as to how they work, if they can be applied here.
struct node {int a; int b;};
int main() {
std::vector<node> V {{1,2}, {3,4}, ...};
}
#include <vector>
using namespace std;
struct node {int a;};
int main() {
std::vector<node> V {node{1}, node{2}};
}
suppose I got a node like this:
struct node{
int a;
int b;
}
Now I want to make a queue structure in cpp. If the data type was int then we could do that easily in this way:
queue<int> a;
And we could also push or pop elements like this: a. push_back(12) or a. pop(12)
But in the earlier case when out data type is user defined how can we make such a queue and push or pop elemeqnts from it?
There is absolutely no problem in holding non-PODs like struct or class inside container like queue.
struct s1{
int a;
string b;
};
class Foo{
int a;
string b;
};
int main() {
queue<int> qi;
queue<s1> qs;
queue<Foo> qfoo;
return 0;
}
// Example program
#include <iostream>
#include <queue>
using namespace std;
struct s1{
int a;
string b;
};
class Foo{
public:
int a;
string b;
};
int main()
{
queue<Foo> q;
Foo obj;
obj.a=2;
obj.b="Object";
q.push(obj);
Foo p=q.back();
cout<<p.a<<endl;
cout<<p.b<<endl;
return 0;
}
If you have
struct node{
int a;
int b;
};
std::queue<node> q;
you can use push as follows:
q.push({ 11, 12 });
this adds a node with a = 11 and b = 12.
This works as long as copy-list-initialization is possible, as it is in this case. Otherwise you would have to use q.push(node{ 11, 12 });
Use queue a; make objects of node type and use functions a.push_back()
a.pop_front() to push and pop respectively.Also don't forget to #include queue.
When I make my own struct, say:
struct myStruct{
int data1;
int data2;
string data3;
}
I can initialize an instance of type myStruct like this:
myStruct instance1;
So my question is, why am I often seeing "struct" written during the initialization of a struct?
Maybe that's an inaccurate statement so here is an example of what I mean:
/*This is a tiny program that checks
to see if a file exists in
the current working directory. */
#include <sys/stat.h>
#include <iostream>
using namespace std;
const string FILENAME = data.txt;
int main(){
struct stat fileStatus; //<-- HERE HERE HERE!
if (FileExists(FILENAME, fileStatus)){
cout << "File Does Exist" << endl;
}else{
cout << "File Does NOT Exist" << endl;
}
return 0;
}
bool FileExists(const string & fileName,struct stat & fileStatus){
bool fileDoesNotExist = stat (fileName.c_str(), &fileStatus);
return !fileDoesNotExist;
}
>
LINE 13: struct stat fileStatus;
Is this something that was done in C for some reason?
Something with a macro or a typedef?
I just don't understand why this is the way it is.
This is a C thing; there's no good reason to continue to do it in C++.1
In C, struct is part of the typename, e.g.:
struct foo { int x; };
defines a type called struct foo. In C++, it defines a type called foo. In C, you can usually hide this irritation behind a typedef:
typedef struct foo { int x; } foo;
1 At least, not in code that couldn't possibly also be compiled as C (such as the example in your question).
You can do what you want by instead calling it like this:
typedef struct mystruct
{
int itema;
int itemb;
Etc...
}* mystruct;
So that's whenever you make a mystruct item it creates a pointer to your struct, else you have to call your struct by
struct mystruct *object;