如何将元素从 std::list 复制到结构数组?
How to copy elements from std::list to an array of struct?
我需要将std::list
的内容复制到数组中,其中数组是数组的结构。下面是它的代码实现。
#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++;
}
}
在这里,我需要 GetDimensions()
函数将列表(作为第一个参数传递)复制到数组(第二个参数)。实现的函数适用于简单数组 plane
。但是如何将结构数组作为参数传递给函数呢?
我将 std::list
作为 cuboid.height
、cuboid.width
和 cuboid.length
。所以函数必须将list
的内容分别从cuboid[0].height
复制到cuboid[i].height
。有没有具体的直接复制内容的功能?
您可以使用 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;
}
请改用 std::array
。那么你的问题可以简化为将两种不同类型的数组传递给一个函数。
这个可以解决
- 通过良好的旧函数重载
- 或在 c++17 函数模板中
if-constexpr.
以下是带有 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;
}
另请注意:
- 您没有指定 return 类型的
GetDimensions
函数。
你可能想要 return void
那里。
在 C++ 中你不需要为 struct { ... }
.
使用 typedef
别名
最后但同样重要的是,不要用using namespace std;
练习
我需要将std::list
的内容复制到数组中,其中数组是数组的结构。下面是它的代码实现。
#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++;
}
}
在这里,我需要 GetDimensions()
函数将列表(作为第一个参数传递)复制到数组(第二个参数)。实现的函数适用于简单数组 plane
。但是如何将结构数组作为参数传递给函数呢?
我将 std::list
作为 cuboid.height
、cuboid.width
和 cuboid.length
。所以函数必须将list
的内容分别从cuboid[0].height
复制到cuboid[i].height
。有没有具体的直接复制内容的功能?
您可以使用 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;
}
请改用 std::array
。那么你的问题可以简化为将两种不同类型的数组传递给一个函数。
这个可以解决
- 通过良好的旧函数重载
- 或在 c++17 函数模板中 if-constexpr.
以下是带有 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;
}
另请注意:
- 您没有指定 return 类型的
GetDimensions
函数。 你可能想要 returnvoid
那里。 在 C++ 中你不需要为
struct { ... }
. 使用 最后但同样重要的是,不要用
using namespace std;
练习
typedef
别名