Converting into multidimensional std::array [duplicate] - c++

This question already has answers here:
Why are "double braces" needed in declaration of multi-dimensional array using stacked std::array?
(2 answers)
Closed 2 years ago.
int data[][4] = { {1,2,3,4}, {9,8,7,6}, {2,4,6,8} };
I want to convert this into multidimensional std::array
array< array<int,4>, 3 > stddata = { {1,2,3,4}, {9,8,7,6}, {2,4,6,8} };
like this.
But error occur in this code. Why does this error occur? and how can I change reset part { {1,2,3,4}, {9,8,7,6}, {2,4,6,8} } to { , } numbers.

Update:
Here is code using std::array
#include <iostream>
#include <array>
int main() {
// your code goes here
std::array< std::array<int, 4>, 3> stddata = {{{1,2,3,4}, {9,8,7,6}, {2,4,6,8}}};
return 0;
}
If the usecase is to add / remove more values during the lifetime of the container, we can use std::vector. Here is sample code:
#include <iostream>
#include <vector>
int main() {
// your code goes here
std::vector< std::vector<int>> stddata = { {1,2,3,4}, {9,8,7,6}, {2,4,6,8} };
return 0;
}

Related

Function, Pointers and 2d arrays [duplicate]

This question already has answers here:
Why does int*[] decay into int** but not int[][]?
(4 answers)
Create a pointer to two-dimensional array
(10 answers)
Closed 2 years ago.
In C++,
We can do the following:
#include <iostream>
int main()
{
int arr[] = {1,2,3};
int *p = arr;
return 0;
}
However this dosen't seem to work:
#include <iostream>
int main()
{
int arr[][3] = {{1,2,3},{4,5,6}};
int **p = arr;
return 0;
}
Can somebody please explain me why it does not work for 2d arrays.
Also when dealing with pointers and 2d arrays, consider the following code:
#include <iostream>
int N = 5;
void func(int arr[][N]){
return;
}
int main()
{
int arr[N][N];
return 0;
}
The above code doesn't work either and i don't know why? Error: expression must have a constant value (Variable N)

How to copy elements from std::list to an array of struct?

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;
}

How to Copy array of vectors, using = raises error Expression:transposed pointer range

I need to copy array of vector passed as reference to constructor/function.
member variable gets the reference to the passed array of vector
while running below code I am getting error Expression: Transposed pointer range
#define MAX 1001
Constructor( std::vector< int > (&Adj)[MAX])
{
(this->Adj[MAX]) = Adj[MAX];
}
If you really want an array of fixed (compile-time) size of std::vector, use std::array
#include <array>
#include <vector>
Constructor (const std::array<std::vector<int>, MAX>& rhs)
{
this->Adj = rhs;
}
and declare Adj as
std::array<std::vector<int>, MAX> Adj
You can use std::copy to copy an array:
#include <cstddef> // size_t
#include <vector> // std::vector<>
#include <algorithm> // std::copy();
constexpr size_t max{ 3 };
struct foo {
std::vector<int> Adj[max];
foo(std::vector<int> (&values)[max])
{
std::copy(std::begin(values), std::end(values), std::begin(Adj));
}
};
int main()
{
std::vector<int> values[max];
foo f{ values };
}

map declaration not compiling [duplicate]

This question already has answers here:
Initializing a static std::map<int, int> in C++
(12 answers)
Closed 5 years ago.
So for some reason this works in a class contructor but not outside a class I was wondering as to why and how could I get my map to work outside a class.
#include <iostream>
#include <string>
#include <map>
typedef std::map <std::string, int> idMap;
idMap type_id;
type_id["Moon"] = 1;
type_id["Star"] = 2;
type_id["Sun"] = 3;
int main()
{
std::cout << type_id["Moon"] << std::endl;
}
The compiler errors I get are as follows
11:1: error: 'type_id' does not name a type 12:1: error: 'type_id' does not name a type 13:1: error: 'type_id' does not name a type
I am looking for an example like this that would work, also if you can tell me why this won't work.
Your main should look like this:
int main()
{
type_id["Moon"] = 1;
type_id["Star"] = 2;
type_id["Sun"] = 3;
std::cout << type_id["Moon"] << std::endl;
}
You cannot put these statements outside of a function (in that case main()).
Or if you really want to populate your map outside main(), you could it by using a list initializer constructor, like this:
idMap type_id { {"Moon", 1}, {"Star", 2}, {"Sun", 3} };
This approach works for a header file as well, like this:
myHeader.h
#include <string>
#include <map>
typedef std::map <std::string, int> idMap;
idMap type_id { {"Moon", 1}, {"Star", 2}, {"Sun", 3} };
main.cpp
#include <iostream>
#include "myHeader.h"
int main() {
std::cout << type_id["Moon"] << std::endl;
}

Return deque-array c++

How do I return an deque array in c++?
private:
deque<int> iHouses[3];
public:
deque<int> getHouses();
//gives me an error when implementing the function of course - but where should I put the brackets?
deque<int> GameEngine::getHouses() {
return this->iHouses;
}
Just use the std::array
#include <array>
....
private:
using my_house_cont = std::array<std::deque<int>, 3>;
my_house_cont m_houses;
public:
my_house_cont getHouses();