2011-11-09 50 views
1

我想知道如何將這樣的C++ 11代碼翻譯成Boost + visual studio 2008:多維數組的創建和迭代通過它,以防其某些集合的一部分?如何將std :: array C++ 11操作轉換爲Boost + VS08?

這裏有雲:

#include <iostream> 
#include <array> 
#include <vector> 
#include <set> 

typedef size_t cell_id; // row * COLS + col 

template <typename T> struct area 
{ 
    T value; 
    std::vector<cell_id> cells; 
}; 

template <typename T, size_t Rows, size_t Cols> 
std::vector<area<T> > getareas(const std::array<std::array<T, Cols>, Rows>& matrix) 
{ 
    std::vector<area<T> > areas; 
    return areas; 
} 


int main(){ 
    typedef std::array<int, 3> row; 
    std::array<row, 4> matrix = { 
     row { 1 , 2, 3, }, 
     row { 1 , 3, 3, }, 
     row { 1 , 3, 3, }, 
     row { 100, 2, 1, }, 
    }; 

    auto areas = getareas(matrix); 

    std::cout << "areas detected: " << areas.size() << std::endl; 
    for (const auto& area : areas) 
    { 
     std::cout << "area of " << area.value << ": "; 
     for (auto pt : area.cells) 
     { 
      int row = pt/3, col = pt % 3; 
      std::cout << "(" << row << "," << col << "), "; 
     } 
     std::cout << std::endl; 
    } 
} 

它magicallyappeared,改變所有std::arrayboost::array不夠=(

#include <iostream> 
#include <array> 
#include <vector> 
#include <set> 
#include <boost/array.hpp> 

typedef size_t cell_id; // row * COLS + col 

template <typename T> struct area 
{ 
    T value; 
    std::vector<cell_id> cells; 
}; 

template <typename T, size_t Rows, size_t Cols> 
std::vector<area<T> > getareas(const boost::array<boost::array<T, Cols>, Rows>& matrix) 
{ 
    std::vector<area<T> > areas; 
    return areas; 
} 


int main(){ 
    typedef boost::array<int, 3> row; 
    boost::array<row, 4> matrix = { 
     row { 1 , 2, 3, }, 
     row { 1 , 3, 3, }, 
     row { 1 , 3, 3, }, 
     row { 100, 2, 1, }, 
    }; 

    auto areas = getareas(matrix); 

    std::cout << "areas detected: " << areas.size() << std::endl; 
    for (const auto& area : areas) 
    { 
     std::cout << "area of " << area.value << ": "; 
     for (auto pt : area.cells) 
     { 
      int row = pt/3, col = pt % 3; 
      std::cout << "(" << row << "," << col << "), "; 
     } 
     std::cout << std::endl; 
    } 
} 

boost::array<row, 4> matrix = ...部分給出了像20級一樣不同的錯誤sintax ...

所以我想知道什麼是正確的翻譯?

+1

嘿嘿 - 很好的問題:)我承認,代碼:) – sehe

回答

2

完成。代碼是活的http://ideone.com/ATY4q

也修復了遞歸範圍檢查中的一個明顯的錯誤。你能發現它嗎?

#include <iostream> 
#include <fstream> 
#include <boost/assign.hpp> 
#include <boost/array.hpp> 
#include <vector> 
#include <set> 

namespace mxdetail 
{ 
    typedef size_t cell_id; // row * COLS + col 

    template <typename T> struct area 
    { 
     T value; 
     typedef std::vector<cell_id> cells_t; 
     cells_t cells; 
    }; 

    template <typename T, size_t Rows, size_t Cols> 
     std::vector<area<T> > getareas(const boost::array<boost::array<T, Cols>, Rows>& matrix) 
    { 
     typedef boost::array<boost::array<T, Cols>, Rows> mtx; 
     std::vector<area<T> > areas; 

     struct visitor_t 
     { 
      const mtx& matrix; 
      std::set<cell_id> visited; 

      visitor_t(const mtx& mtx) : matrix(mtx) { } 

      area<T> start(const int row, const int col) 
      { 
       area<T> result; 
       visit(row, col, result); 
       return result; 
      } 

      void visit(const int row, const int col, area<T>& current) 
      { 
       const cell_id id = row*Cols+col; 
       if (visited.end() != visited.find(id)) 
        return; 

       bool matches = current.cells.empty() || (matrix[row][col] == current.value); 

       if (matches) 
       { 
        visited.insert(id); 
        current.value = matrix[row][col]; 
        current.cells.push_back(id); 

        // process neighbours 
        for (int nrow=std::max(0, row-1); nrow < std::min((int) Rows, row+2); nrow++) 
        for (int ncol=std::max(0, col-1); ncol < std::min((int) Cols, col+2); ncol++) 
         /* if (ncol!=col || nrow!=row) */ 
          visit(nrow, ncol, current); 
       } 
      } 
     } visitor(matrix); 

     for (int r=0; r < (int) Rows; r++) 
      for (int c=0; c < (int) Cols; c++) 
      { 
       mxdetail::area<int> area = visitor.start(r,c); 
       if (!area.cells.empty()) // happens when startpoint already visited 
        areas.push_back(area); 
      } 

     return areas; 
    } 
} 


template <typename T, size_t N> 
    boost::array<T, N> make_array(const T (&a)[N]) 
{ 
    boost::array<T, N> result; 
    std::copy(a, a+N, result.begin()); 
    return result; 
} 

int main() 
{ 
    typedef boost::array<int, 3> row; 

    int row0[] = { 1 , 2, 3, }; 
    int row1[] = { 1 , 3, 3, }; 
    int row2[] = { 1 , 3, 3, }; 
    int row3[] = { 100, 2, 1, }; 

    boost::array<row, 4> matrix; 
    matrix[0] = make_array(row0); 
    matrix[1] = make_array(row1); 
    matrix[2] = make_array(row2); 
    matrix[3] = make_array(row3); 

    typedef std::vector<mxdetail::area<int> > areas_t; 
    typedef areas_t::value_type::cells_t cells_t; 

    areas_t areas = mxdetail::getareas(matrix); 
    for (areas_t::const_iterator it=areas.begin(); it!=areas.end(); ++it) 
    { 
     std::cout << "area of " << it->value << ": "; 
     for (cells_t::const_iterator pit=it->cells.begin(); pit!=it->cells.end(); ++pit) 
     { 
      int row = *pit/3, col = *pit % 3; 
      std::cout << "(" << row << "," << col << "), "; 
     } 
     std::cout << std::endl; 
    } 
    std::cout << "areas detected: " << areas.size() << std::endl; 

} 

輸出:

area of 1: (0,0), (1,0), (2,0), 
area of 2: (0,1), 
area of 3: (0,2), (1,1), (1,2), (2,1), (2,2), 
area of 100: (3,0), 
area of 2: (3,1), 
area of 1: (3,2), 
areas detected: 6 
+0

是的!它編譯!) – Rella

+0

@Bobby此外,它運行!這需要一些修復,因爲boost :: array(幸運的是)在默認情況下做了一些更好的索引邊界檢查 – sehe

+0

那件事支持所有最新的增強版本SVN? – Rella

0

模擬廣義的初始化語法會有些困難。您可能必須單獨分配元素,創建後。

您還必須用顯式類型替換auto關鍵字,然後切換到舊的for循環語法。

實際上,這整個文件看起來像是新的C++ 11功能的演示。你可能會更好地重新開始,並且設計一個更適合C++ 03的限制的設計。

+0

我跟你說,鑑於C++ 03我會不會用了boost ::陣列<>。但是,我可以從我的答案中看到翻譯。是非統一的初始化是一個婊子(我也非常失望,沒有像'template array :: array(const T(&a)[N])'在boost :: array中的構造函數... – sehe

0

我相信你的問題是因爲VS2008(和大多數其他的pre-C++ 11編譯器)不支持「初始化器列表」,這是你如何初始化C++ 11中的用戶定義集合。

例如,你不能說

矢量<INT> V = {1,2,3,4,5};

in C++ 03,but you can in C++ 11。

而且,當然,你也不能使用「自動」。

auto areas = getareas(matrix); 

或新的for循環語法:

for (auto pt : area.cells) 
0

matrix聲明是用C++ 11的初始化語法;據推測,你的編譯器不支持。沒有簡單的方法來初始化多維boost::array;之後您需要分配每個元素。

boost::array<row, 4> matrix; 
matrix[0][0] = 1; 
// ... 
matrix[3][2] = 1; 

或者,您可以編寫一個將其參數組裝到數組中的make_array函數。但是,如果沒有可變參數模板,則需要爲要支持的每個數組大小寫入重載。

boost::array<row, 4> matrix = make_array(
    make_array(1,2,3), 
    make_array(1,3,3), 
    make_array(1,3,3), 
    make_array(100,2,1)); 

另一種可能性是使用一個普通的數組,超載getareas爲:

template <typename T, size_t Rows, size_t Cols> 
std::vector<area<T> > getareas(T (&matrix)[Rows][Cols]); 

int matrix[4][3] = {{1,2,3}, {1,3,3}, {1,3,3}, {100,2,1}}; 

auto areas = getareas(matrix); // if "auto" works for you 
2

std::array,所以你應該能夠在底層使用集合初始化語法數組直接。也就是說,不是這樣的:

typedef std::array<int, 4> V4; 
typedef std::array<V4, 4> M44; 

M44 m { { 1,2,3,4}, {3,4,5,6}, {2,1,3,2}, {1,5,3,2} }; 

你可以只寫一個赤裸裸的數組:

int[4][4] m = { { 1,2,3,4}, {3,4,5,6}, {2,1,3,2}, {1,5,3,2} }; 
+0

的麻煩是,他沒有C++ 0x。我發佈了翻譯,這是我自己的C++ 11代碼到另一個問題在這裏:http://stackoverflow.com/questions/8039896/having-a-matrix-mxn整數 - 如何將它們分組到多邊形中 - with-boost-geome/8044058#8044058 – sehe

+0

@sehe:這與C++ 11有什麼關係?2D數組是完全正常的C++ 98 ... –

+0

嗯,對不起,我以爲你解釋瞭如何使用統一初始化,OP特別要求MSVC2008 + Boost,不過所以我想這就是爲什麼我認爲你會轉向boost :: array – sehe

相關問題