Related
I can't figure out how to do it; it's driving me nuts.
#include <iostream>
#include <memory>
#include <map>
int main()
{
std::map<std::string, std::unique_ptr<std::string>> map;
std::unique_ptr<std::string> bar(new std::string("bar"));
map["foo"] = std::move(bar);
std::cout << "foo: " << *(map["foo"]) << std::endl;
}
This compiles just fine on gcc v4.9.2:
$ g++ -std=c++0x test.cc -o test
Unfortunately, all I have available to me is gcc v4.4.7, which produces a hideous error message that I'll stick at the bottom.
I can push_back unique_ptrs into vectors just fine; I don't understand why there's an issue with map.
I've also tried using insert:
int main()
{
std::map<std::string, std::unique_ptr<std::string>> map;
std::unique_ptr<std::string> bar(new std::string("bar"));
auto pair = std::make_pair("foo", std::move(bar));
map.insert(std::move(pair));
std::cout << "foo: " << *(map["foo"]) << std::endl;
}
I can make the pair just fine, but when I try to move it into insert I get the error. It appears that it's trying to call the copy constructor for some reason, but I don't understand why, since I'm moveing it.
emplace has the same result:
int main()
{
std::map<std::string, std::unique_ptr<std::string>> map;
std::unique_ptr<std::string> bar(new std::string("bar"));
auto pair = std::make_pair("foo", std::move(bar));
map.emplace(std::move(pair));
std::cout << "foo: " << *(map["foo"]) << std::endl;
}
Both of these compile fine in g++ v4.9.2, but not in v4.4.7.
Anyone have any ideas on an alternative way to do this (in v4.4.7)?
Full error message output (from the first example):
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algobase.h:66,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/char_traits.h:41,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ios:41,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream:40,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iostream:40,
from test.cc:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/unique_ptr.h: In copy constructor 'std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::pair(const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)':
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:68: instantiated from 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ext/new_allocator.h:111: instantiated from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, _Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Tp = std::_Rb_tree_node<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:394: instantiated from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:881: instantiated from 'std::_Rb_tree_iterator<_Val> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(const std::_Rb_tree_node_base*, const std::_Rb_tree_node_base*, const _Val&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:1215: instantiated from 'std::_Rb_tree_iterator<_Val> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique_(std::_Rb_tree_const_iterator<_Val>, const _Val&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:540: instantiated from 'typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, const std::pair<const _Key, _Tp>&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:450: instantiated from '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
test.cc:9: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/unique_ptr.h:214: error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp_Deleter = std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:68: error: used here
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/map:60,
from test.cc:3:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h: In constructor 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]':
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:136: note: synthesized method 'std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::pair(const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)' first required here
GCC 4.4.7 does not provide full support for C++ 11 features, so it is unrealistic to expect all C++ 11 features to work properly. In this particular case, the compiler is not generating move assignment and move copy methods for you. So, when std::map attempts assignment or copy, it uses the regular default ones, which are deleted for unique_ptr.
If you just need a smart pointer, you can use shared_ptr instead.
std::map<std::string, std::shared_ptr<std::string>> map;
std::shared_ptr<std::string> bar = std::make_shared<std::string>("bar");
map["foo"] = bar;
I have looked into the issue. STL implementation for map correctly has a move constructor defined in it:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
_Rb_tree_node(_Args&&... __args)
: _Rb_tree_node_base(),
_M_value_field(std::forward<_Args>(__args)...) { }
#endif
};
Moreover, this is called, as stated in the error output. std::pair has move constructor defined as well, but this one is not called.
I believe, std::forward and deduced type of Args is at fault:
usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:
In constructor ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...)
[with _Args = const std::pair<..., std::unique_ptr<...> >&,
As you see, type of _Args is a const reference, which is forwarded by forward, and regular pair constructor is called.
I assume, one might fiddle with stl_tree.h to fix it - for example, by removing std::forward and just casting the arg to rvalue reference. This would not be correct, of course, but might work for specific case.
I am trying to insert a values into the boost map but the call to the insert statement is ambiguous in boost map insert.
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <functional>
#include <utility>
using namespace boost::interprocess;
int main ()
{
// remove earlier existing SHM
shared_memory_object::remove("SharedMemoryName");
// create new
managed_shared_memory segment(create_only,"SharedMemoryName",65536);
//Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
//so the allocator must allocate that pair.
typedef std::string KeyType;
typedef map<std::string, int> MappedType;
typedef std::pair<const KeyType, MappedType> ValueType;
//allocator of for the map.
typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;
//Initialize the shared memory STL-compatible allocator
ShmemAllocator alloc_inst (segment.get_segment_manager());
//third parameter argument is the ordering function is used to compare the keys.
typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MySHMMap;
//offset ptr within SHM for map
offset_ptr<MySHMMap> m_pmap = segment.construct<MySHMMap>("MySHMMapName")(std::less<std::string>(), alloc_inst);
//Insert data in the map
std::string my_string = "test";
m_pmap[0].insert(std::make_pair( my_string, 0) );
return 0;
}
The boost APIs that get called are:
std::pair<iterator,bool> insert(const nonconst_value_type& x)
std::pair<iterator,bool> insert(const value_type& x)
typedef typename tree_t::value_type value_type;
typedef std::pair<key_type, mapped_type> nonconst_value_type;
Error Log:
/home/user/droy/src/quotes/shmmutimap/src/writer.cxx:39: error: call of overloaded 'insert(std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>)' is ambiguous
/home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/interprocess/containers/container/map.hpp:410: note: candidates are: std::pair<typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::iterator, bool> boost::container::map<Key, T, Pred, Alloc>::insert(const typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::value_type&) [with Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, T = boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, Pred = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Alloc = boost::interprocess::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >]
/home/dev/build/third_party/64-rhel5/boost_1_47_0/include/boost/interprocess/containers/container/map.hpp:421: note: std::pair<typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::iterator, bool> boost::container::map<Key, T, Pred, Alloc>::insert(const std::pair<typename boost::container::containers_detail::rbtree<Key, std::pair<const Key, T>, boost::container::containers_detail::select1st<std::pair<const Key, T> >, Pred, Alloc>::key_type, T>&) [with Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, T = boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, Pred = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Alloc = boost::interprocess::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::container::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >]
The parameters to the insert statement end up to be the same type,how could I get around this problem, any hints?
Right now, you create a map<string, map<string, int>>. I imagine that your intention was to create just a map<string, int>. To do that, you need a very simple fix to your code:
// typedef map<std::string, int> MappedType;
typedef int MappedType;
As an aside, you could also write the last line of your code as:
// m_pmap[0].insert(std::make_pair( my_string, 0) );
m_pmap[0][my_string] = 0;
Updates:
As it appears that my intuition was wrong, and you did want to create a map<string, map<string, int>>, then the response is slightly different.
Note that your call is basically attempting to do this:
map<string, int> x(0);
m_pmap[0][my_string] = x;
Note that there is no constructor for map<string, int> that takes an integer. Instead, you could do any of:
m_pmap[0].insert(std::make_pair( my_string, map<std::string, int>()));
m_pmap[0].insert(std::make_pair( my_string, MappedType()));
m_pmap[0][my_string] = map<std::string, int>();
m_pmap[0][my_string] = MappedType();
You could also simply take advantage of how the map works, and do:
m_pmap[0]["us"]["abc"] = 2030;
m_pmap[0]["us"]["def"] = 1230;
I can't find what I'm doing wrong here. The function eta does what I ask but when I use it in the loop I get the attached error.
bool eta(map<string, TLorentzVector> map_jets, string jet){
return( fabs(map_jets[jet].PseudoRapidity()) > 2.5 );
}
and then
vector<pair<string,double> > jets_pt( vec_jets.size() );
for( vector<pair<string,double> >::iterator it = jets_pt.begin(); it != jets_pt.end(); ++it)
jets_pt.erase(remove_if(jets_pt.begin(),jets_pt.end(),eta(map_jets,it1->first)),jets_pt.end);
I get the error
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h: In function '_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, _OutputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>*, std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double> > > >, _OutputIterator = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>*, std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double> > > >, _Predicate = bool]':
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:1291: instantiated from '_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>*, std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double> > > >, _Predicate = bool]'
/misc/cdf/gbertoli/hww/Diboson_v20_taus/Ana/src/Functions.cc:25: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:1216: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h: In function '_RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>*, std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double> > > >, _Predicate = bool]':
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:338: instantiated from '_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>*, std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double> > > >, _Predicate = bool]'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:1287: instantiated from '_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>*, std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, double> > > >, _Predicate = bool]'
/misc/cdf/gbertoli/hww/Diboson_v20_taus/Ana/src/Functions.cc:25: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:260: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:264: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:268: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:272: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:280: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:284: error: '__pred' cannot be used as a function
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:288: error: '__pred' cannot be used as a function
mv: cannot stat `/misc/cdf/gbertoli/hww/Diboson_v20_taus/tmp/Linux2.6-GCC_4_1/Ana/srt_dep_tmp.27294': No such file or directory
gmake[2]: *** [/misc/cdf/gbertoli/hww/Diboson_v20_taus/tmp/Linux2.6-GCC_4_1/Ana/libAna-shared/Functions.o] Error 1
gmake[1]: *** [src.lib] Error 2
gmake: *** [Ana.all] Error 2
First off, the only valid signature for remove_if takes a single function as the predicate argument:
jets_pt.erase(std::remove_if(jets_pt.begin(), jets_pt.end(), eta),
jets_pt.end());
This means that eta must be a function returning bool and taking precisely one argument whose type is the value type of the container:
bool eta(const std::pair<string, double> & p)
{
// do something useful with p
}
If this doesn't fit your bill because you need additional state information in the predicate, then you need to make it a function object:
struct Eta
{
const std::map<string, TLorentzVector> & map_jets;
Eta(const std::map<string, TLorentzVector> & m) : map_jets(m) { }
bool operator()(const std::pair<string, double> & p) const
{
std::map<string, TLorentzVector>::const_iterator it = map_jets.find(p->second);
return it == map_jets.end() ?
false :
std::fabs(it->second.PseudoRapidity()) > 2.5;
}
};
Now you have to use remove_if with an instance of Eta:
jets_pt.erase(std::remove_if(jets_pt.begin(), jets_pt.end(), Eta(map_jets)),
jets_pt.end()); // ^^^^^^^^^^^^^
Note that your use of the for loop is extremely suspicious; you should double-check that.
std::remove_if takes a value of the contained type (bool pred (container::value_type), or a functor which overloads operator() appropriately).
For std::map, you have to do it like explained here remove_if equivalent for std::map .
You're passing a bool (the results of calling eta) to remove_if as
the third argument. You need to pass it a predicate: a pointer to a
function taking a single argument and returning something which can be
converted to a bool, or a functional object. In the error messages,
__pred is your third argument; remove_if calls it here with a
pair<string, double>, and expects a bool in return. You have to
provide something which can be called like this. (You might want to
look into boost::bind.)
And BTW: passing a map by value to eta might not be a good idea.
It's going to slow things down considerably if the map is big.
I have this code:
////
// Default Namespaces
///
using namespace std;
typedef map <string, boost::shared_mutex> t_map_shared_mutex;
int main(int argc, char** argv) {
t_map_shared_mutex list_lock;
boost::shared_mutex global_lock;
string i = "ABC";
boost::unique_lock < boost::shared_mutex > l_lock ( global_lock );
boost::unique_lock < boost::shared_mutex > lock ( list_lock[i] );
//Do Something with that lock
lock.unlock();
l_lock.unlock();
}
This generates the following error. From what I understand (and I could be pretty wrong here) g++ is telling me that the mutex is being passed as a const value... And I can't see why.
In file included from /usr/include/c++/4.4/utility:63,
from /usr/include/boost/config/no_tr1/utility.hpp:21,
from /usr/include/boost/config/select_stdlib_config.hpp:33,
from /usr/include/boost/config.hpp:40,
from /usr/include/boost/date_time/compiler_config.hpp:12,
from /usr/include/boost/date_time/posix_time/posix_time.hpp:14,
from prova.cpp:5:
/usr/include/c++/4.4/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = boost::shared_mutex]’:
/usr/include/c++/4.4/bits/stl_map.h:450: instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = boost::shared_mutex, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >]’
prova.cpp:66: instantiated from here
/usr/include/c++/4.4/bits/stl_pair.h:84: error: no matching function for call to ‘boost::shared_mutex::shared_mutex(const boost::shared_mutex&)’
/usr/include/boost/thread/pthread/shared_mutex.hpp:47: note: candidates are: boost::shared_mutex::shared_mutex()
/usr/include/boost/thread/pthread/shared_mutex.hpp:21: note: boost::shared_mutex::shared_mutex(boost::shared_mutex&)
/usr/include/c++/4.4/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _U2 = boost::shared_mutex, _T1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = boost::shared_mutex]’:
/usr/include/c++/4.4/ext/new_allocator.h:105: instantiated from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex>]’
/usr/include/c++/4.4/bits/stl_tree.h:371: instantiated from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(const _Val&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex>, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >]’
/usr/include/c++/4.4/bits/stl_tree.h:881: instantiated from ‘std::_Rb_tree_iterator<_Val> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(const std::_Rb_tree_node_base*, const std::_Rb_tree_node_base*, const _Val&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex>, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >]’
/usr/include/c++/4.4/bits/stl_tree.h:1215: instantiated from ‘std::_Rb_tree_iterator<_Val> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique_(std::_Rb_tree_const_iterator<_Val>, const _Val&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex>, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >]’
/usr/include/c++/4.4/bits/stl_map.h:540: instantiated from ‘typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, const std::pair<const _Key, _Tp>&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = boost::shared_mutex, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >]’
/usr/include/c++/4.4/bits/stl_map.h:450: instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = boost::shared_mutex, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::shared_mutex> >]’
prova.cpp:66: instantiated from here
/usr/include/c++/4.4/bits/stl_pair.h:101: error: no matching function for call to ‘boost::shared_mutex::shared_mutex(const boost::shared_mutex&)’
/usr/include/boost/thread/pthread/shared_mutex.hpp:47: note: candidates are: boost::shared_mutex::shared_mutex()
/usr/include/boost/thread/pthread/shared_mutex.hpp:21: note: boost::shared_mutex::shared_mutex(boost::shared_mutex&)
How to solve that ?
STL containers require a copy constructor for the value type; since mutexes can't be copied, you can't put them directly into a map. You must use a pointer to a mutex (perhaps via std::unique_ptr or boost::ptr_map) instead.
It seems to me as std::map is trying to call the copy constructor of boost::shared_mutex by passing it a const boost::shared_mutex&, but no such constructor is available:
/usr/include/c++/4.4/bits/stl_pair.h:84: error: no matching function for call to ‘boost::shared_mutex::shared_mutex(const boost::shared_mutex&)’
/usr/include/boost/thread/pthread/shared_mutex.hpp:47: note: candidates are: boost::shared_mutex::shared_mutex()
/usr/include/boost/thread/pthread/shared_mutex.hpp:21: note: boost::shared_mutex::shared_mutex(boost::shared_mutex&)
I'm relatively new to C++, so I kind of glaze over when I see these monstrous template involving errors.
Here's my code:
#include "scene.hpp"
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
// projects a ray from the eyepoint through (x, y) in the image plane
Ray Camera::project_ray(int x, int y){
}
class scene_parser{
public:
class unimplemented_exception {};
class unknown_command_exception {};
class malformed_command_exception {};
scene_parser(Scene &s);
void parse(const std::string &filename);
private:
PixelBufferPTR current_texture;
Colour current_material_colour;
Material current_material;
typedef void (scene_parser::*parsefunc )(std::vector<std::string>);
std::map<std::string, parsefunc> funcMap;
void init_funcMap();
void apply_func(const std::vector<std::string> &line);
// methods which parse the scene file
// they each receive a line of the file, tokenized on whitespace
void camera_from(std::vector<std::string> line);
void camera_target(std::vector<std::string> line);
void camera_forw(std::vector<std::string> line);
void camera_up(std::vector<std::string> line);
void camera_angle(std::vector<std::string> line);
void camera_resolution(std::vector<std::string> line);
void sphere(std::vector<std::string> line);
void tsphere(std::vector<std::string> line);
void texture(std::vector<std::string> line);
void mesh(std::vector<std::string> line) {throw unimplemented_exception();}
void background(std::vector<std::string> line);
void ambient_light(std::vector<std::string> line);
void parallel_light(std::vector<std::string> line);
void point_light(std::vector<std::string> line);
void spot_light(std::vector<std::string> line) {throw unimplemented_exception();}
void material(std::vector<std::string> line);
void render(std::vector<std::string> line);
void trace_depth(std::vector<std::string> line);
};
scene_parser::scene_parser(Scene &s) : current_material_colour(0, 0, 0), current_material(0, 0, 0, 0, 0) {
init_funcMap();
}
void scene_parser::init_funcMap(){
funcMap["camera_from"] = &scene_parser::camera_from;
funcMap["camera_target"] = &scene_parser::camera_target;
funcMap["camera_forw"] = &scene_parser::camera_forw;
funcMap["camera_up"] = &scene_parser::camera_up;
funcMap["camera_angle"] = &scene_parser::camera_angle;
funcMap["camera_resolution"] = &scene_parser::camera_resolution;
funcMap["sphere"] = &scene_parser::sphere;
funcMap["tsphere"] = &scene_parser::tsphere;
funcMap["texture"] = &scene_parser::texture;
funcMap["mesh"] = &scene_parser::mesh;
funcMap["background"] = &scene_parser::background;
funcMap["ambient_light"] = &scene_parser::ambient_light;
funcMap["parallel_light"] = &scene_parser::parallel_light;
funcMap["point_light"] = &scene_parser::point_light;
funcMap["spot_light"] = &scene_parser::spot_light;
funcMap["material"] = &scene_parser::material;
funcMap["render"] = &scene_parser::render;
funcMap["trace_depth"] = &scene_parser::trace_depth;
}
void scene_parser::apply_func(const std::vector<std::string> &line){
if(line.size() != 0){
std::map<std::string, parsefunc>::iterator it = funcMap.find(line[0]);
if(it == funcMap.end()) throw unknown_command_exception();
else{
parsefunc f = it->second;
this->*f(line); //line 86
}
}
}
void scene_parser::parse(const std::string &filename){
std::vector<std::string> lines = tokenize_string(file_to_string(filename), "\n");
std::vector<std::vector<std::string> > tokenized_lines;
tokenized_lines.resize(lines.size());
std::transform(lines.begin(), lines.end(), tokenized_lines.begin(), tokenized_lines.end(), std::bind2nd(std::ptr_fun(tokenize_string), std::string(" "))); //line 97
std::for_each(tokenized_lines.begin(), tokenized_lines.end(), std::mem_fun(&scene_parser::apply_func)); //line 99
}
and this is tokenize_string
std::vector<std::string> tokenize_string(const std::string &s, const std::string &split_chars);
and here are the errors:
Scene.cpp: In member function ‘void scene_parser::apply_func(const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’:
Scene.cpp:86: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’, e.g. ‘(... ->* f) (...)’
In file included from /usr/include/c++/4.4/bits/stl_function.h:712,
from /usr/include/c++/4.4/memory:66,
from light.hpp:4,
from Scene.hpp:4,
from Scene.cpp:1:
/usr/include/c++/4.4/backward/binders.h: At global scope:
/usr/include/c++/4.4/backward/binders.h: In instantiation of ‘std::binder2nd<std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >’:
Scene.cpp:97: instantiated from here
/usr/include/c++/4.4/backward/binders.h:152: error: ‘typename _Operation::result_type std::binder2nd<_Operation>::operator()(typename _Operation::first_argument_type&) const [with _Operation = std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’ cannot be overloaded
/usr/include/c++/4.4/backward/binders.h:146: error: with ‘typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
In file included from /usr/include/c++/4.4/algorithm:62,
from Scene.cpp:5:
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) [with _IIter1 = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _IIter2 = __gnu_cxx::__normal_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, _OIter = __gnu_cxx::__normal_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, _BinaryOperation = std::binder2nd<std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]’:
Scene.cpp:97: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:4741: error: no match for call to ‘(std::binder2nd<std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >) (std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’
/usr/include/c++/4.4/backward/binders.h:146: note: candidates are: typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = std::pointer_to_binary_function<const std::string&, const std::string&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, _Funct = std::mem_fun1_t<void, scene_parser, const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>]’:
Scene.cpp:99: instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:4200: error: no match for call to ‘(std::mem_fun1_t<void, scene_parser, const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>) (std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’
/usr/include/c++/4.4/bits/stl_function.h:604: note: candidates are: _Ret std::mem_fun1_t<_Ret, _Tp, _Arg>::operator()(_Tp*, _Arg) const [with _Ret = void, _Tp = scene_parser, _Arg = const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&]
It was compiled with gcc 4.4 on Ubuntu 10.10.
I'd be grateful for any insight.
Scene.cpp: In member function ‘void scene_parser::apply_func(const std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’:
Scene.cpp:86: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’, e.g. ‘(... ->* f) (...)’
Note the latter part of the second line. You simply have to use parentheses with pointers-to-member-functions (PTMFs):
void scene_parser::apply_func(const std::vector<std::string> &line) {
if (line.size() != 0) {
std::map<std::string, parsefunc>::iterator it = funcMap.find(line[0]);
if (it == funcMap.end()) throw unknown_command_exception();
else {
parsefunc f = it->second;
(this->*f)(line); // line 86 (fixed)
}
}
}
I'd simply use a "normal" for loop to "fix" the other errors; it's unfortunate that template errors can be so nasty and I hate it too.
std::vector<std::vector<std::string> > tokenized_lines;
tokenized_lines.reserve(lines.size());
// c++0x: for (auto const &x : lines) {
for (std::vector<std::string>::const_iterator x = lines.begin(); x != lines.end(); ++x) {
tokenized_lines.push_back(tokenize_string(*x), " "); // no dereference in 0x
tokenized_lines.back().apply_func();
}