GNOME Bugzilla – Bug 343967
Cannot compile accumulators that change the signal return type
Last modified: 2010-12-23 21:46:53 UTC
I'm using libsigc++ 2.0.16 on Gentoo Linux, and trying to write an accumulator for the first time, one that takes slots that return int and returns a std::vector<int>. Unfortunately, I get a compile error - it seems that the iterators passed to the accumulator are picking-up on the accumulator result_type, instead of the slot result_type, leading to errors. Does anyone have an example of an accumulator whose result type differs from the slot result_type? Thanks in advance, Tim Shead #include <sigc++/signal.h> #include <vector> class accumulate { public: typedef std::vector<int> result_type; template<typename IteratorT> result_type operator()(IteratorT First, IteratorT Last) { result_type result; for(; First != Last; ++First) result.push_back(*First); return result; } }; int foo() { return 1; } int bar() { return 2; } int main(int argc, char* argv[]) { sigc::signal0<int, accumulate> signal; signal.connect(sigc::ptr_fun(foo)); signal.connect(sigc::ptr_fun(bar)); std::vector<int> results = signal.emit(); return 0; } $ gcc -o test test.cpp -I/usr/include/sigc++-2.0 -I/usr/lib/sigc ++-2.0/include -lstdc++ -lsigc-2.0 test.cpp: In member function `std::vector<int, std::allocator<int> > accumulate::operator()(IteratorT, IteratorT) [with IteratorT = sigc::internal::slot_iterator_buf<sigc::internal::signal_emit0<int, accumulate>, std::vector<int, std::allocator<int> > >]': /usr/include/sigc++-2.0/sigc++/signal.h:453: instantiated from `static typename T_accumulator::result_type sigc::internal::signal_emit0<T_return, T_accumulator>::emit(sigc::internal::signal_impl*) [with T_return = int, T_accumulator = accumulate]' /usr/include/sigc++-2.0/sigc++/signal.h:1702: instantiated from `typename sigc::internal::signal_emit0<T_return, T_accumulator>::result_type sigc::signal0<T_return, T_accumulator>::emit() const [with T_return = int, T_accumulator = accumulate]' test.cpp:38: instantiated from here test.cpp:25: error: no matching function for call to `std::vector<int, std::allocator<int> >::push_back(std::vector<int, std::allocator<int> >)' /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/include/g ++-v3/bits/stl_vector.h:596: error: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int, _Alloc = std::allocator<int>] /usr/include/sigc++-2.0/sigc++/signal.h: In member function `T_result sigc::internal::slot_iterator_buf<T_emitter, T_result>::operator*() const [with T_emitter = sigc::internal::signal_emit0<int, accumulate>, T_result = std::vector<int, std::allocator<int> >]': test.cpp:25: instantiated from `std::vector<int, std::allocator<int> > accumulate::operator()(IteratorT, IteratorT) [with IteratorT = sigc::internal::slot_iterator_buf<sigc::internal::signal_emit0<int, accumulate>, std::vector<int, std::allocator<int> > >]' /usr/include/sigc++-2.0/sigc++/signal.h:453: instantiated from `static typename T_accumulator::result_type sigc::internal::signal_emit0<T_return, T_accumulator>::emit(sigc::internal::signal_impl*) [with T_return = int, T_accumulator = accumulate]' /usr/include/sigc++-2.0/sigc++/signal.h:1702: instantiated from `typename sigc::internal::signal_emit0<T_return, T_accumulator>::result_type sigc::signal0<T_return, T_accumulator>::emit() const [with T_return = int, T_accumulator = accumulate]' test.cpp:38: instantiated from here /usr/include/sigc++-2.0/sigc++/signal.h:296: error: no match for 'operator=' in 'this->sigc::internal::slot_iterator_buf<sigc::internal::signal_emit0<int, accumulate>, std::vector<int, std::allocator<int> > >::r_ = this->sigc::internal::slot_iterator_buf<sigc::internal::signal_emit0<int, accumulate>, std::vector<int, std::allocator<int> > >::c_->sigc::internal::signal_emit0<T_return, T_accumulator>::operator() [with T_return = int, T_accumulator = accumulate]((+(&this->std::_List_iterator<_Tp, _Ref, _Ptr>::operator* [with _Tp = sigc::slot_base, _Ref = const sigc::slot_base&, _Ptr = const sigc::slot_base*]())))' /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/include/g ++-v3/bits/vector.tcc:128: error: candidates are: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = int, _Alloc = std::allocator<int>] distcc[12622] ERROR: compile test.cpp on localhost failed
You are right - this look like a bug! Most likely, in signal.h.m4, definition of struct signal_emit$1, line: typedef internal::slot_iterator_buf<self_type> slot_iterator_buf_type; should read: typedef internal::slot_iterator_buf<self_type,T_return> slot_iterator_buf_type; Could you file a bug report, please? Thanks! Martin
This bug was fixed in the Git repository on 2009-12-29, wasn't it? The ChangeLog mentions bug 586436, and bug 586436 comment 1 mentions this bug. I've run the test case in this bug with a version of libsigc++ that I newly cloned from the Git repository. It compiles and runs all right.
OK. Thanks. *** This bug has been marked as a duplicate of bug 586436 ***