Итак, я писал программу на C++, которая позволила бы мне взять под контроль весь мир. Я все сделали писать окончательные единицы перевода, но я получил сообщение об ошибке:Почему bind1st и bind2nd требуют постоянных объектов функции?
error C3848: expression having type 'const `anonymous-namespace'::ElementAccumulator<T,BinaryFunction>' would lose some const-volatile qualifiers in order to call 'void `anonymous-namespace'::ElementAccumulator<T,BinaryFunction>::operator()(const point::Point &,const int &)'
with
[
T=SideCounter,
BinaryFunction=std::plus<int>
]
c:\program files (x86)\microsoft visual studio 9.0\vc\include\functional(324) : while compiling class template member function 'void std::binder2nd<_Fn2>::operator()(point::Point &) const'
with
[
_Fn2=`anonymous-namespace'::ElementAccumulator<SideCounter,std::plus<int>>
]
c:\users\****\documents\visual studio 2008\projects\TAKE_OVER_THE_WORLD\grid_divider.cpp(361) : see reference to class template instantiation 'std::binder2nd<_Fn2>' being compiled
with
[
_Fn2=`anonymous-namespace'::ElementAccumulator<SideCounter,std::plus<int>>
]
Я посмотрел в спецификации binder2nd
и там это было: он принял const
AdaptibleBinaryFunction.
Так что, неважно, подумал я. Я просто использовал boost::bind
, не так ли?
Неверно! Теперь моя программа take-over-the-world занимает слишком много времени для компиляции (bind
используется внутри шаблона, который создается очень много)! В этом случае мой заклятый враг первым захватит мир! Я не могу этого допустить - он использует Java!
Так может кто-то сказать мне, почему это дизайнерское решение было принято? Это похоже на странное решение. Я предполагаю, что я должен сделать некоторые из элементов моего класса mutable
сейчас ...
EDIT: Нарушитель код:
template <typename T, typename BinaryFunction>
class ElementAccumulator
: public binary_function<typename T::key_type, typename T::mapped_type, void>
{
public:
typedef T MapType;
typedef typename T::key_type KeyType;
typedef typename T::mapped_type MappedType;
typedef BinaryFunction Func;
ElementAccumulator(MapType& Map, Func f) : map_(Map), f_(f) {}
void operator()(const KeyType& k, const MappedType& v)
{
MappedType& val = map_[k];
val = f_(val, v);
}
private:
MapType& map_;
Func f_;
};
void myFunc(int n)
{
typedef boost::unordered_map<Point, int, Point::PointHash> Counter;
Counter side_count;
ElementAccumulator<SideCounter, plus<int> > acc(side_count, plus<int>());
vector<Point> pts = getPts();
for_each(pts.begin(), pts.end(), bind2nd(acc, n));
}
Не работает ли это, если вы просто создали свой 'operator() const'? AFAIK, это не повлияет на какие-либо ссылочные элементы (не делает объект refferred постоянным), поэтому вы все равно можете изменить карту. – UncleBens