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;
}