2017-12-07 9 views
1

サイズ、タイプ、または寸法に関係なく、行列の文字列への変換を実現したいと考えています。テンプレートを使用して、私は必要な行列の「ソート」ごとに1つのテンプレートを定義することで、テンプレートを使用できるようにしました。アレイ用テンプレートを使用して異なる次元の行列を扱う方法は?

テンプレート:2-dimensionnal行列の

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

は、テンプレート:

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

しかし、私は唯一の汎用テンプレートを持っていることによって、解決策は、より 'エレガント' したいのですがそれらの次元に関係なく行列を扱うことができる。それを行う方法はありますか?

+0

動的なサイズのベクトルか何かを使用しないのはなぜですか? – xander

+0

counterpoint:あなたのマトリックスは実際にその寸法にテンプレート化される必要がありますか?私はマトリックスクラスを実装していましたが、それをテンプレート化することから始めましたが、すぐにそれをやめ、ディメンションを正規のメンバにすることが容易であることを発見しました。そうするために)。それは、テンプレートは単に "generic" _の特定の定義の汎用性を助長するだけなので、テンプレートを使用するよりも汎用*です。 –

+2

私は他のコメントに同意しますが、今のところ、2番目のスニペットの内部ループを 'to_string(arr [i]) 'の呼び出しで置き換えることができます。 –

答えて

1

まずは、関数に標準関数の名前を指定しないようにしてください。したがって、次の例では、std::to_stringとの衝突の危険を避けるために、fooString()の名前を関数に変更しました。

第2の問題:Bob__によって観察されるように、内部ループをto_string(arr[i])(私の名前を付けてfooString(arr[i]))という呼び出しで置き換えると、多次元(次元ごとに)配列の問題が再帰的に解決されます。第

:私は、単一の値に対してstd::to_string()を取得グランドケース(Tintfloatような塩基(いない配列)型である、等)

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

を書くことを示唆していると再帰的なケースでは、1つの以上の間接レベル(その性能は、おそらく、少し悪化している)が、アレイ管理のロジックを持っている基本型を扱うグランドケース付き

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

になります1つの関数内にあり、2つではほとんど等しくはありません(コードを維持するエラーが発生しにくい)。

以下は、完全な作業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; 
} 
+0

ありがとう、魅力的な私が期待していたよりも簡単です!サイドノート:これらのテンプレートは実際には標準関数との衝突を防ぐために_namespace_にカプセル化されています。 –

関連する問題