c++ 如何替换此代码中的自动引用关键字?[duplicate]

ugmeyewa  于 2023-01-15  发布在  其他
关注(0)|答案(4)|浏览(143)
    • 此问题在此处已有答案**:

Passing an array by reference(5个答案)
Passing a 2D array to a C++ function(16个答案)
C++ pass an array by reference(7个答案)
2天前关闭。
你好,我想找到一种方法来取代汽车关键字在下面的代码。

#include <iostream>

using namespace std;

void printMatrix(const auto & matrix) {
    /* print matrix using range-based for */
}

int main() {
    int matrix[][3] = {{}, {}, {}};
    int matrix2[][6] = {{}, {}, {}};
    printMatrix(matrix);
    printMatrix(matrix2);
    return 0;
}

我应该用什么来替换常量自动&矩阵中的自动。我可以使用指针,但问题是我必须传递行和列的大小。上面的代码是工作的,但我想知道如何自动关键字处理这一点。

wi3ka0sx

wi3ka0sx1#

此函数声明

void printMatrix(const auto & matrix) {
    /* print matrix using range-based for */
}

声明一个模板函数。
你可以这样写

template <typename T, size_t M, size_t N>
void printMatrix(const T ( & matrix)[M][N]) {
    /* print matrix using range-based for */
}

并且该函数作为前一个函数被调用

printMatrix(matrix);
printMatrix(matrix2);

因为数组的元素类型是已知的,所以你也可以写

template <size_t M, size_t N>
void printMatrix(const int ( & matrix)[M][N]) {
    /* print matrix using range-based for */
}

//...

printMatrix(matrix);
printMatrix(matrix2);

在函数中,您可以在嵌套的for循环中使用值MN来输出数组,例如

for ( size_t i = 0; i < M; i++ )
{
    for ( size_t j = 0; j < N; j++ )
    {
        std::cout << matrix[i][j] << ' ';
    }
    std::cout << '\n';
}

或者可以使用基于范围的for循环

for ( const auto &row : matrix )
{
    for ( const auto &item : row )
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';
}

你也可以使用初始化函数来完成同样的工作,例如

#include <iterator>

//...

void printMatrix(const auto & matrix) {
    for ( size_t i = 0, m = std::size( matrix ); i < m; i++ )
    {
        for ( size_t j = 0, n = std::size( matrix[i] ); j < n; j++ )
        {
            std::cout << matrix[i][j] << ' ';
        }
        std::cout << '\n';
    }
}

这是一个演示程序。

#include <iostream>
#include <iterator>

std::ostream & printMatrix( const auto &matrix, std::ostream &os = std::cout )
{
    for (size_t i = 0, m = std::size( matrix ); i < m; i++)
    {
        for (size_t j = 0, n = std::size( matrix[i] ); j < n; j++)
        {
            os << matrix[i][j] << ' ';
        }
        os << '\n';
    }

    return os;
}

int main()
{
    int matrix[][3] = 
    { 
        { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } 
    };

    int matrix2[][6] = 
    { 
        { 0, 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0, 1 }, { 2, 3, 4, 5, 6, 7 } 
    };

    printMatrix( matrix ) << '\n';
    printMatrix( matrix2 ) << '\n';
}

程序输出为

0 1 2
3 4 5
6 7 8

0 1 2 3 4 5
6 7 8 9 0 1
2 3 4 5 6 7
aurhwmvo

aurhwmvo2#

对于参数化元素类型,重新声明print函数,以便仅允许作为2D数组的函数参数通过引用:

#include <cstddef>  // std::size_t

template<typename T, std::size_t num_rows, std::size_t num_cols>
void printMatrix(T const (&mat)[num_rows][num_cols]) {
    /* print matrix using range-based for */
}

// ....
printMatrix(matrix);  // template arguments inferred as <int, 3, 3>
printMatrix(matrix2); // template arguments inferred as <int, 3, 6>

与使用单个类型模板参数的重载(如OP的示例中,通过具有单个发明类型模板参数的auto/缩写函数模板)相比,这本质上是一个更专业化的版本。

arknldoa

arknldoa3#

一个好的替代品可以是一个概念。
here开始:

template<typename T>
concept nested_range = std::ranges::range<T> && std::ranges::range<std::ranges::range_value_t<T>>;

所以

template <nested_range Matrix>
void printMatrix(const Matrix & matrix) {
  for (const auto& line: matrix) {
      for (const auto& x: line) {
          std::cout << x << " ";
      }
      std::cout << "\n";
  }
}

这样,在代码中示出了仅期望包含可迭代对象(例如2D数组)的可迭代对象(概念范围),并且对于错误的参数将给出合理的错误消息。
Live example有足够多的包含。

xqkwcwgp

xqkwcwgp4#

你可以用模板参数替换auto,这是C++14之前的做法。

#include <iostream>

using namespace std;

template <typename Matrix>
void printMatrix(const Matrix & matrix) {
    /* print matrix using range-based for */
}

int main() {
    int matrix[][3] = {{}, {}, {}};
    int matrix2[][6] = {{}, {}, {}};
    printMatrix(matrix);
    printMatrix(matrix2);
    return 0;
}

相关问题