关于c ++:查找通过引用传递的容器的维度

Find dimensions of a container passed by reference

我写了以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <vector>
#include <iomanip>


using std::cin; using std::cout; using std::endl;

int DivideTwoFactorials(int m, int n)
{
    int div(1);
    while (m > n)
    {
        div *= m;
        m--;
    }
    return div;
}

int Factorial(int m)
{
    int fact(1);
    for (int i(1); i <=m; i++) fact *= i;
    return fact;
}

int BinomialCoefficient(int m, int n)
{
    return (DivideTwoFactorials(m, n) * (1./Factorial(m-n)));
}

template <typename Type>
void Modify3DContainer(Type &a, int fun(int, int), int p = 0, int q = 0)
{
    int m(a.size());
    int n(a[0].size());
    int z(a[0][0].size());

    for (int i(0); i < m; i++)
    {
        for (int j(0); j < n; j++)
        {
            for (int k(0); k < z; k++)
            {
                if (a[i][j][k] == fun(p, q)) a[i][j][k] = a[i][j][k] * a[i][j][k];
            }
        }
    }
}

int main()
{
    cout << endl <<"Input dimensions of 3D container:";
    int m, n, p;

    cin >> m >> n >> p;

    std::vector<std::vector<std::vector<int>>> a(m, std::vector<std::vector<int>>(n, std::vector<int>(p)));
    cout << endl <<"Input elements of 3D container:";
    int x;
    for (int i(0); i < m; i++)
    {
        for (int j(0); j < n; j++)
        {
            for (int k(0); k < p; k++)
            {
                cin >> x;
                a[i][j][k] = x;
            }
        }
    }

    Modify3DContainer(a, BinomialCoefficient, 6, 4);

    cout << endl <<"Modified 3D container:" << endl << endl;

    for (int i(0); i < m; i++)
    {
        for (int j(0); j < n; j++)
        {
            for (int k(0); k < p; k++)
            {
                cout << std::setw(6) << a[i][j][k];
            }
            cout << endl;
        }
        cout << endl;
    }
    return 0;
}

关于"modify3dcontainer"函数有一个问题,它接受以下参数:

  • 三维容器上的引用
  • 返回一个int并接收两个int参数的函数。
  • 两个int参数,默认值为0。

当函数接收到p和q作为参数时,函数应该在3d容器中找到与第二个参数定义的函数的返回值相等的所有元素,并用它们的平方值替换这些元素。这里的问题是函数"MuffFy3dCube"接受多种类型的容器,而我不允许将容器的尺寸传递给所述函数(C++编程赋值)。该函数目前只适用于使用size()方法的向量向量向量,但不适用于常规数组。我尝试使用sizeof运算符,但它不适用于多维向量。使用typeid检查容器的类型可能是一种可能的解决方案,但是有许多组合需要检查,因为3D容器可以,例如,是deques向量的向量等。

所以我的问题是,有没有办法找到传递的3D容器的大小,不管它的类型如何?

谢谢您。


如果你真的想知道尺寸,那么你要找的是std::size。它将告诉您传递给它的原始数组或具有size成员函数的对象的大小。不幸的是,它是C++ 17的特性,所以在使用的编译器中可能没有可用的特性。

幸运的是,它的机制已经存在于当前的标准中,因此我们可以像前面链接中提供的可能实现那样编写自己的机制。

1
2
3
4
5
6
7
8
9
10
11
template <class C>
constexpr auto size(const C&amp; c) -> decltype(c.size())
{
    return c.size();
}

template <class T, std::size_t N>
constexpr auto size(const T (&amp;array)[N]) noexcept
{
    return N;
}

把它们用在

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    std::vector<std::vector<std::vector<int>>> vec(10, std::vector<std::vector<int>>(20, std::vector<int>(30, 0)));
    int arr[10][20][30];

    std::cout << size(vec) <<"\t" << size(arr) <<"
"
;
    std::cout << size(vec[0]) <<"\t" << size(arr[0]) <<"
"
;
    std::cout << size(vec[0][0]) <<"\t" << size(arr[0][0]) <<"
"
;
    return 0;
}

我们得到

1
2
3
10  10
20  20
30  30

LIve示例

如果不需要大小,但只需要循环,那么可以使用基于范围的for循环或常规循环,并使用与容器和数组一起使用的std::beginstd::end