C++ 如何翻译std::array C++;11项行动以促进+;VS08?
我想知道如何将这样的C++11代码翻译成Boost+visual studio 2008:多维数组的创建和迭代,以防它是某个集合的一部分 下面是:C++ 如何翻译std::array C++;11项行动以促进+;VS08?,c++,visual-studio,visual-studio-2008,boost,c++11,C++,Visual Studio,Visual Studio 2008,Boost,C++11,我想知道如何将这样的C++11代码翻译成Boost+visual studio 2008:多维数组的创建和迭代,以防它是某个集合的一部分 下面是: #include <iostream> #include <array> #include <vector> #include <set> typedef size_t cell_id; // row * COLS + col template <typename T> struct a
#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;
}
}
boost::array matrix=…
part给出了大约20个不同的相似sintax错误
所以我想知道什么是正确的翻译?要模拟通用初始值设定项语法会有点困难。您可能需要在创建后单独指定图元 您还必须用显式类型替换
auto
关键字,并切换到旧的for循环语法
事实上,整个文件看起来像是新的C++11特性的演示。您最好重新开始,设计一个更符合C++03限制的设计。要模拟通用初始值设定项语法有些困难。您可能需要在创建后单独指定图元 您还必须用显式类型替换
auto
关键字,并切换到旧的for循环语法
事实上,整个文件看起来像是新的C++11特性的演示。您最好重新开始,设计一个更符合C++03限制的设计。我认为您的问题是因为VS2008(以及大多数其他预C++11编译器)不支持“初始值设定项列表”,而“初始值设定项列表”正是您在C++11中初始化用户定义集合的方式 例如,你不能说 向量v={1,2,3,4,5} 在C++03中,但可以在C++11中使用 当然,你也不能用“自动” 或新的for循环语法:
我认为您的问题是因为VS2008(以及大多数其他c++11之前的编译器)不支持“初始值设定项列表”,这是在c++11中初始化用户定义集合的方式 例如,你不能说 向量v={1,2,3,4,5} 在C++03中,但可以在C++11中使用 当然,你也不能用“自动” 或新的for循环语法:
matrix
的声明使用C++11的初始化语法;您的编译器可能不支持这一点。没有简单的方法初始化多维boost::array
;之后需要分配每个元素
boost::array<row, 4> matrix;
matrix[0][0] = 1;
// ...
matrix[3][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
模板
std::向量getarea(T(&matrix)[行][Cols]);
int矩阵[4][3]={{1,2,3},{1,3,3},{1,3,3},{100,2,1};
自动区域=获取区域(矩阵);//如果“自动”适合你
矩阵的声明使用C++11的初始化语法;您的编译器可能不支持这一点。没有简单的方法初始化多维boost::array
;之后需要分配每个元素
boost::array<row, 4> matrix;
matrix[0][0] = 1;
// ...
matrix[3][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
模板
std::向量getarea(T(&matrix)[行][Cols]);
int矩阵[4][3]={{1,2,3},{1,3,3},{1,3,3},{100,2,1};
自动区域=获取区域(矩阵);//如果“自动”适合你
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} };
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} };
完成了。代码是实时的
还修复了递归范围检查中的一个明显错误。你能认出它吗
#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;
}
完成了。代码是实时的
还修复了递归范围检查中的一个明显错误。你能认出它吗
#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;
}
呵呵-好问题:)我认识那个代码:)呵呵-好问题:)我认识那个代码:)问题是,他没有c++0x。我发布了翻译,这是我自己的C++11代码到另一个问题:嗯。很抱歉我以为你解释了如何使用统一初始化。OP特别要求使用MSVC2008+Boost,不过我想这就是为什么我认为您会转向Boost::array,但他没有int
数组,他有一个强类型对象数组。看起来它们有一个用户定义的构造函数。@BenVoigt:只要我们讨论的是一个数组,聚合初始化仍然有效。@BenVoigt:你的论点是骗人的。“聚合”意味着你可以说(实际上你可以)cda[]={cd(1,0),cd(2,1)}代码>。“聚合”的定义以及随后的初始化语法是递归的std::complex
似乎不是聚合类型。问题是,他没有c++0x。我发布了翻译,这是我自己的C++11代码到另一个问题:嗯。很抱歉我以为你解释了如何使用统一初始化。OP特别要求使用MSVC2008+Boost,不过我想这就是为什么我认为您会转向Boost::array,但他没有int
数组,他有一个强类型对象数组。看起来它们有一个用户定义的构造函数。@BenVoigt:只要我们讨论的是一个数组,聚合初始化仍然有效。@BenVoigt:你的论点是骗人的。“聚合”意味着你可以说(实际上你可以)cda[]={cd(1,0),cd(2,1)}代码>。“聚合”的定义以及随后的初始化语法是递归的std::complex
似乎不是聚合类型。我同意你的观点,因为C++03我不会使用boost::array。然而,正如你从我的回答中所看到的,翻译是可以进行的。是的,非统一初始化是一个棘手的问题(我也很失望boost::array中没有像template array::array(const T(&a)[N])
这样的构造函数……我同意你的看法,考虑到C++03,我不会使用
#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