Mat*_*att 6 c++ shared-ptr function-object stl-algorithm
我有一组shared_ptr,我想将remove_copy_if与谓词的自定义函数对象一起使用.我不知道"最好"的方式.现在,我有这个工作:
class CellInCol : public std::unary_function<const std::shared_ptr<Cell>,
bool>
{
public:
CellInCol( size_t col ) : _col( col ) {}
bool operator() ( const std::shared_ptr<Cell> &a ) const
{
return ( a->GetX() == _col );
}
private:
size_t _col;
};
typedef std::set<std::shared_ptr<Cell>, CellSorter> Container;
Container _grid;
// initialization omitted...
Puzzle::Container Puzzle::GetCol( size_t c )
{
Cell::Validate( c, 1, 9 );
Container col;
std::remove_copy_if( _grid.begin(), _grid.end(),
std::inserter( col, col.begin() ),
std::not1( CellInCol( c ) ) );
return col;
}
Run Code Online (Sandbox Code Playgroud)
我决定对shared_ptr执行const引用,因为该对象不会保留指针,这似乎比shared_ptr的额外副本更有效.
看起来对对象进行const引用似乎更好,但是我无法编译它.我把它改成了这个,但没有运气:
class CellInCol : public std::unary_function<const Cell,
bool>
{
public:
CellInCol( size_t col ) : _col( col ) {}
// note use of const ref to shared_ptr's
bool operator() ( const Cell &a ) const
{
return ( a.GetX() == _col );
}
private:
size_t _col;
};
Run Code Online (Sandbox Code Playgroud)
这是g ++的输出:
In file included from /usr/include/c++/4.4/algorithm:62,
from /usr/include/c++/4.4/valarray:41,
from Puzzle.h:5,
from Puzzle.cpp:2:
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_OIter std::remove_copy_if(_IIter, _IIter, _OIter, _Predicate) [with _IIter = std::_Rb_tree_const_iterator<std::shared_ptr<Sudoku::Cell> >, _OIter = std::insert_iterator<std::set<std::shared_ptr<Sudoku::Cell>, Sudoku::CellSorter, std::allocator<std::shared_ptr<Sudoku::Cell> > > >, _Predicate = std::unary_negate<Sudoku::<unnamed>::CellInRow>]’:
Puzzle.cpp:100: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:938: error: no match for call to ‘(std::unary_negate<Sudoku::<unnamed>::CellInRow>) (const std::shared_ptr<Sudoku::Cell>&)’
/usr/include/c++/4.4/bits/stl_function.h:357: note: candidates are: bool std::unary_negate<_Predicate>::operator()(const typename _Predicate::argument_type&) const [with _Predicate = Sudoku::<unnamed>::CellInRow]
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_OIter std::remove_copy_if(_IIter, _IIter, _OIter, _Predicate) [with _IIter = std::_Rb_tree_const_iterator<std::shared_ptr<Sudoku::Cell> >, _OIter = std::insert_iterator<std::set<std::shared_ptr<Sudoku::Cell>, Sudoku::CellSorter, std::allocator<std::shared_ptr<Sudoku::Cell> > > >, _Predicate = std::unary_negate<Sudoku::<unnamed>::CellInCol>]’:
Puzzle.cpp:110: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:938: error: no match for call to ‘(std::unary_negate<Sudoku::<unnamed>::CellInCol>) (const std::shared_ptr<Sudoku::Cell>&)’
/usr/include/c++/4.4/bits/stl_function.h:357: note: candidates are: bool std::unary_negate<_Predicate>::operator()(const typename _Predicate::argument_type&) const [with _Predicate = Sudoku::<unnamed>::CellInCol]
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_OIter std::remove_copy_if(_IIter, _IIter, _OIter, _Predicate) [with _IIter = std::_Rb_tree_const_iterator<std::shared_ptr<Sudoku::Cell> >, _OIter = std::insert_iterator<std::set<std::shared_ptr<Sudoku::Cell>, Sudoku::CellSorter, std::allocator<std::shared_ptr<Sudoku::Cell> > > >, _Predicate = std::unary_negate<Sudoku::<unnamed>::CellInBlock>]’:
Puzzle.cpp:121: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:938: error: no match for call to ‘(std::unary_negate<Sudoku::<unnamed>::CellInBlock>) (const std::shared_ptr<Sudoku::Cell>&)’
/usr/include/c++/4.4/bits/stl_function.h:357: note: candidates are: bool std::unary_negate<_Predicate>::operator()(const typename _Predicate::argument_type&) const [with _Predicate = Sudoku::<unnamed>::CellInBlock]
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_OIter std::remove_copy_if(_IIter, _IIter, _OIter, _Predicate) [with _IIter = std::_Rb_tree_const_iterator<std::shared_ptr<Sudoku::Cell> >, _OIter = std::insert_iterator<std::set<std::shared_ptr<Sudoku::Cell>, Sudoku::CellSorter, std::allocator<std::shared_ptr<Sudoku::Cell> > > >, _Predicate = std::unary_negate<Sudoku::<unnamed>::CellIsNeighbor>]’:
Puzzle.cpp:154: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:938: error: no match for call to ‘(std::unary_negate<Sudoku::<unnamed>::CellIsNeighbor>) (const std::shared_ptr<Sudoku::Cell>&)’
/usr/include/c++/4.4/bits/stl_function.h:357: note: candidates are: bool std::unary_negate<_Predicate>::operator()(const typename _Predicate::argument_type&) const [with _Predicate = Sudoku::<unnamed>::CellIsNeighbor]
make: *** [Puzzle.o] Error 1
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以做到这一点,还是有任何建议?
首先,由于您使用的是 C++0x 功能 ( std::shared_ptr),因此使用std::copy_if()来避免调用是有意义的std::not1。
您编写的第一个函子有效,最小的可编译示例如下所示: https: //ideone.com/XhuNu
正如编译器指出的那样,第二个函子不起作用,因为它的 argument_type (即const Cell)与调用它的参数(即 )之间不匹配const std::shared_ptr<Cell>&。
这根本就不是容器所含的东西!据目前所知,这些 Cell 对象甚至可能不可复制。
如果容器是一组 Cell,而不是一组指向 Cell 的共享指针,那么使用第二个函子确实会更好。无论如何,避免对象的共享所有权被认为是良好的设计。
使用第二个函子编译的示例代码
#include <set>
#include <functional>
#include <algorithm>
#include <iostream>
struct Cell {
int mX;
Cell(int x) : mX(x) {}
size_t GetX() const { return mX;}
};
struct CellSorter {
bool operator()(const Cell& l, const Cell& r) const
{
return l.GetX() < r.GetX();
}
};
// your second functor begins
class CellInCol : public std::unary_function<const Cell,
bool>
{
public:
CellInCol( size_t col ) : _col( col ) {}
// note use of const ref to shared_ptr's
bool operator() ( const Cell &a ) const
{
return ( a.GetX() == _col );
}
private:
size_t _col;
};
// your second functor ends
int main()
{
typedef std::set<Cell, CellSorter> Container;
Container _grid = {Cell(1), Cell(2), Cell(7), Cell(10)};
Container col;
size_t c = 7;
std::remove_copy_if( _grid.begin(), _grid.end(),
std::inserter( col, col.begin() ),
std::not1( CellInCol( c ) ) );
std::cout << "col has " << col.size() << " elements\n"
<< "the first element is " << col.begin()->GetX() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
测试运行: https: //ideone.com/kLiFn
| 归档时间: |
|
| 查看次数: |
2175 次 |
| 最近记录: |