如何将元素从 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.heightcuboid.widthcuboid.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。那么你的问题可以简化为将两种不同类型的数组传递给一个函数。

这个可以解决

以下是带有 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;

  • 练习