C++ 如何使用模板处理不同维度的矩阵?

C++ 如何使用模板处理不同维度的矩阵?,c++,c++11,templates,C++,C++11,Templates,我希望实现矩阵到字符串的转换,而不考虑其大小、类型或维度。通过使用模板,我为我需要的每一种矩阵定义了一个模板,从而使它能够正常工作 阵列的模板: template < typename NUM, std::size_t SIZE > std::string to_string( const std::array< NUM, SIZE > &arr ) { std::string buf; for ( uint32_t i = 0; i <

我希望实现矩阵到字符串的转换,而不考虑其大小、类型或维度。通过使用模板,我为我需要的每一种矩阵定义了一个模板,从而使它能够正常工作

阵列的模板:

template < typename NUM, std::size_t SIZE >
std::string to_string( const std::array< NUM, SIZE > &arr ) {

    std::string buf;
    for ( uint32_t i = 0; i < SIZE; i++ )
        buf += std::to_string( arr[i] ) + " ";

    return buf;
}
模板
std::string到_string(const std::array&arr){
std::字符串buf;
对于(uint32_t i=0;i
二维矩阵的模板:

template < typename NUM, std::size_t INNER_SIZE, std::size_t OUTER_SIZE >
std::string to_string( const std::array< std::array<NUM, INNER_SIZE>, OUTER_SIZE > &arr ) {

    std::string buf;

    for ( uint32_t i = 0; i < OUTER_SIZE; i++ ) {
        for ( uint32_t j = 0; j < INNER_SIZE; j++ )
            buf += std::to_string( arr[i][j] ) + " ";
    }

    return buf;
}
template
std::string到_string(const std::array&arr){
std::字符串buf;
对于(uint32_t i=0;i

然而,我希望通过只使用一个通用模板来处理矩阵,而不管矩阵的维数如何,从而使解决方案更加“优雅”。有办法吗

首先:我强烈建议不要给你的函数起与标准函数相同的名字。因此,在下面的示例中,我重命名了
fooString()
函数,以避免与
std::to_string
冲突的风险

第二:正如Bob所观察到的,如果用调用
to\u string(arr[i])
fooString(arr[i])
,通过我的重命名来替换内部循环,则可以递归地解决多维(针对每个维度)数组的问题

第三:我建议编写一个基本情况,为单个值获取
std::to_string()
(其中
T
是基(而不是数组)类型,如
int
float
,等等)

模板
std::string fooString(T const&val)
{return std::to_string(val);}
递归的情况变成了

template <typename T, std::size_t Dim>
std::string fooString (std::array<T, Dim> const & arr)
 {
    std::string buf;

    for ( auto const & elem : arr )
        buf += fooString( elem ) + " ";

    return buf;
}
模板
std::string fooString(std::array const&arr)
{
std::字符串buf;
用于(自动常量和元素:arr)
buf+=fooString(elem)+';
返回buf;
}
对于处理基类型的基本情况,您有一个更高级别的间接寻址(因此性能可能稍差),但阵列管理的逻辑仅在一个函数中,而在两个函数中几乎不相等(维护代码时不太容易出错)

下面是一个完整的C++11工作示例

#include <array>
#include <string>
#include <iostream>

template <typename T>
std::string fooString (T const & val)
 { return std::to_string(val); }

template <typename T, std::size_t Dim>
std::string fooString (std::array<T, Dim> const & arr)
 {
    std::string buf;

    for ( auto const & elem : arr )
        buf += fooString( elem ) + " ";

    return buf;
}

int main()
 {
   std::array<std::array<std::array<int, 2U>, 3U>, 4U> a3dim
    {{ {{ {{  2,  3 }}, {{  5,  7 }}, {{ 11, 13 }} }},
       {{ {{ 17, 19 }}, {{ 23, 29 }}, {{ 31, 37 }} }},
       {{ {{ 41, 43 }}, {{ 47, 53 }}, {{ 59, 61 }} }},
       {{ {{ 67, 71 }}, {{ 73, 79 }}, {{ 83, 89 }} }} }};

   std::cout << fooString(a3dim) << std::endl;
 }
#包括
#包括
#包括
模板
std::string fooString(T const&val)
{return std::to_string(val);}
模板
std::string fooString(std::array const&arr)
{
std::字符串buf;
用于(自动常量和元素:arr)
buf+=fooString(elem)+';
返回buf;
}
int main()
{
阵列a3dim
{{ {{ {{  2,  3 }}, {{  5,  7 }}, {{ 11, 13 }} }},
{{ {{ 17, 19 }}, {{ 23, 29 }}, {{ 31, 37 }} }},
{{ {{ 41, 43 }}, {{ 47, 53 }}, {{ 59, 61 }} }},
{{ {{ 67, 71 }}, {{ 73, 79 }}, {{ 83, 89 }} }} }};

std::为什么不使用动态大小向量或其他东西呢?对位:你的矩阵真的需要在其维度上进行模板化吗?我在不久前实现了一个矩阵类a,并开始对其进行模板化,但很快发现,停止这样做要容易得多,并且让维度成为常规成员,使用
向量
支持和逻辑索引(并验证尝试这样做)。这比使用模板更通用,因为模板仅对“通用”的某些定义提供通用性我同意其他评论,但现在,您可以开始注意到第二个代码段中的内部循环可以被对
的调用替换为对_string(arr[I])的调用
谢谢,它看起来很有魅力,比我预期的要简单得多!旁注:这些模板确实封装在名称空间中,以防止与标准函数发生冲突。
#include <array>
#include <string>
#include <iostream>

template <typename T>
std::string fooString (T const & val)
 { return std::to_string(val); }

template <typename T, std::size_t Dim>
std::string fooString (std::array<T, Dim> const & arr)
 {
    std::string buf;

    for ( auto const & elem : arr )
        buf += fooString( elem ) + " ";

    return buf;
}

int main()
 {
   std::array<std::array<std::array<int, 2U>, 3U>, 4U> a3dim
    {{ {{ {{  2,  3 }}, {{  5,  7 }}, {{ 11, 13 }} }},
       {{ {{ 17, 19 }}, {{ 23, 29 }}, {{ 31, 37 }} }},
       {{ {{ 41, 43 }}, {{ 47, 53 }}, {{ 59, 61 }} }},
       {{ {{ 67, 71 }}, {{ 73, 79 }}, {{ 83, 89 }} }} }};

   std::cout << fooString(a3dim) << std::endl;
 }