I had a problem when using Eclipse CDT with detecting stl information. I got in-editor errors like "symbol vector could not be resolved". I have solved this using the solution described here:
https://stackoverflow.com/a/13524483/613173
However, it seems that stl::map still has problems. For example, the line
std::map<int,int> a;
Gets the "invalid template arguments" error. Also,
a.begin();
Gives "method 'begin' could not be resolved" error.
However, with default parameters given explicitly:
std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > b;
I got none of those errors. This does not happen with other classes such as std::vector whose template also has more than one argument but I get no complaints over
std::vector<int> a;
Another problem regards iterators. Even if the map was defined with all parameters given explicitly, the "first" and "second" fields give an error:
std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::iterator i_b = b.begin();
i_b->first;
This gives "Field 'first' could not be resolved".
Compilation works without problems, obviously, but I still want to be able to use Eclipse's static error detection and auto completion.
Eclipse 4.4.2, CDT 8.6.
Related
I'm using templates while implementing AVL trees on Ubuntu.
The file will not compile when I write template class AVLTree<std::list<int> >;, it tells me:
undefined reference to `AVLTree < std::__cxx11::list < std::__cxx11::basic_string < char, std::char_traits < char>, std::allocator < char> >, std::allocator < std::__cxx11::basic_string < char, std::char_traits < char>, std::allocator < char> > > > >::insert(std::__cxx11::basic_string < char, std::char_traits < char>, std::allocator < char> >)'
And I don't get what it doesn't have the reference to.
But it compiles just fine when I write template class AVLTree<std::list<string> >;
I need to let AVLTree store linked lists that store string values.
Why does one compile and the other doesn't? How to solve my problem?
PS: I've included <list>, <string>, and <iostream>, along with my own header file.
Examining the error message closely shows that linker cannot find the AVLTree::insert(string) method.
Based on the sparse information that you posted, my best hypothesis is that you changed the template parameter in the following line from list<string> to list<int>:
template class AVLTree<std::list<string>>;
This line of code explicitly tells the compiler to instantiate a version of the AVLTree template using list<string> as the template parameter. Thus, when you try to compile the code after the change it gives you the error message that it cannot find the AVLTree::insert(string) function because the compiler is now generating the code for list<int> instead.
Your program contains other code that is referencing AVLTree<list<string>>. At a minimum you will have to update that code to use list<int> as well.
Plus, if you simplify the problem down to something you can post the code for on this site, then you will either find the issue during that process or at least have a change of getting a good answer.
I want to be able to get the address and print a single pair from an STL container using GDB.
E.g., given the following toy program:
#include <map>
int main()
{
std::map<int,int> amap;
amap.insert(std::make_pair(1,2));
}
which I compile as:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
Then, when I try to examine a single element of map, for example:
p amap.begin()
I get:
"Cannot evaluate function -- may be in-lined"
Why is this happening and how do I work around it?
Tested in Ubuntu 20.04, GCC 9.3.0, 2.34.
This is because amap.begin() does not exist in resulting binary. This is how C++ templates work: if you don't use or explicitly instantiate some template method it is not generated in resulting binary.
If you do want to call amap.begin() from gdb you have to instantiate it. One way to do it is to instantiate all methods of std::map:
#include <map>
template class std::map<int,int>;
int main()
{
std::map<int,int> amap;
amap.insert(std::make_pair(1,2));
}
gdb session:
(gdb) p amap.begin()
$1 = {first = 1, second = 2}
#ks1322 has the correct answer. Here are some additional information that may be useful in the future.
Only the constructor, destructor and insert methods on std::map are in the debuginfo:
(gdb) info functions std::map
All functions matching regular expression "std::map":
File /usr/include/c++/6/bits/stl_map.h:
std::pair<std::_Rb_tree_iterator<std::pair<int const, int> >, bool> std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::insert<std::pair<int, int>, void>(std::pair<int, int>&&);
void std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::map();
void std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::~map();
Still, we can call both the size and empty methods:
(gdb) p amap.size()
$1 = 1
(gdb) p amap.empty()
$2 = false
That's because gdb has something called xmethods, a python API for calling mockup functions meant to work identically to the functions that have not been instantiated. The libstdc++ xmethods can be found here. If we disable them, then the same error message appears:
(gdb) disable xmethod
(gdb) p amap.size()
Cannot evaluate function -- may be inlined
(gdb) p amap.empty()
Cannot evaluate function -- may be inlined
(gdb)
I have a C++ program that uses the CGAL 4.5.2_0 library, installed using macports. Recently, I have been getting compile-time warnings that the CGAL/AABB_polyhedron_triangle_primitive.h header is deprecated and that I now should start using CGAL/AABB_face_graph_triangle_primitive.h, so I naively switched the header name and also added the CGAL/boost/graph/graph_traits_Polyhedron_3.h header file which now seems to be necessary to interface with the Boost Graph Library. I noticed also from examples in the CGAL documentation that one of my typedefs needed to be updated from
typedef CGAL::AABB_polyhedron_triangle_primitive<K,Polyhedron> Primitive;
to
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
And so far, that is the extent of what I have done. But now I am getting two new errors at compile time:
In file included from ./Particle.h:44:
/opt/local/include/CGAL/AABB_tree.h:810:27: error: no matching conversion for functional-style cast from 'CGAL::internal::In_place_list_iterator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<My_facet<CGAL::HalfedgeDS_list_types<CGAL::Epick, CGAL::I_Polyhedron_derived_items_3<My_items>, std::__1::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Vector_3<CGAL::Epick> > > >, std::__1::allocator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<My_facet<CGAL::HalfedgeDS_list_types<CGAL::Epick, CGAL::I_Polyhedron_derived_items_3<My_items>, std::__1::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Vector_3<CGAL::Epick> > > > > >' to 'Primitive' (aka 'CGAL::AABB_face_graph_triangle_primitive<CGAL::Polyhedron_3<CGAL::Epick, My_items, HalfedgeDS_default, std::__1::allocator<int> >, CGAL::Default, CGAL::Boolean_tag<true>, CGAL::Boolean_tag<false> >')
m_primitives.push_back(Primitive(first));
In file included from ./Particle.h:45:
/opt/local/include/CGAL/AABB_traits.h:63:33: error: no matching member function for call to 'construct_shared_data'
m_primitive_data=Primitive::construct_shared_data();
~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
/opt/local/include/CGAL/AABB_tree.h:268:15: note: in instantiation of member function 'CGAL::internal::AABB_tree::AABB_traits_base<CGAL::AABB_face_graph_triangle_primitive<CGAL::Polyhedron_3<CGAL::Epick, My_items, HalfedgeDS_default, std::__1::allocator<int> >, CGAL::Default, CGAL::Boolean_tag<true>, CGAL::Boolean_tag<false> >, true>::set_shared_data' requested here
{m_traits.set_shared_data();}
^
If anyone has experience switching from the deprecated header file to the new one, I will be grateful for any advice you might have about how I should proceed.
I can post the header file for the Particle class that seems to be the problem, but it is 3282 lines long and I'm not sure which part(s) I should post.
In response to comment, here is the code that is used to insert primitives in the tree:
// The next chunk creates the 3D polyhedron, storing it in surface_poly
Polyhedron surface_poly = getSurfacePolyhedronFromImage(fname,centroid,xBB,yBB,zBB);
// First translate its centroid to the origin
// CartesianVector is a typedef of CGAL's Vector_3
const CartesianVector translation_vector(-centroid[0],-centroid[1],-centroid[2]);
Aff_transformation_3 transl(CGAL::TRANSLATION, translation_vector);
transform(surface_poly.points_begin(),surface_poly.points_end(),
surface_poly.points_begin(),transl);
// Now the centroid is the origin
centroid.resize(3,0.0);
CartesianPoint origin(0.0,0.0,0.0);
// Construct the AABB tree for quick intersection queries
cout << "Creating AABB tree from polyhedron" << endl;
cout.flush();
Tree tree(surface_poly.facets_begin(),surface_poly.facets_end());
// Object intersection will hold the point of intersection with the surface
boost::optional<Object_and_primitive_id> intersection;
The syntax for the Tree constructor is incorrect for the Polyhedron_3 in the code above. The correct syntax should be
Tree tree(faces(surface_poly).first, faces(surface_poly).second, surface_poly);
Updating the syntax to the correct form fixes the compile-time errors.
Okay, very stumped on this one. Works with Visual Studio, but not Code::Blocks (GNU compiler).
transform(m_teams.begin(), m_teams.end(), inserter(teamNames, teamNames.end()),
[](stVecPair team) -> string { return team.first; });
m_teams is a map : typedef map<string, vector<Person*> > stVecMap;
teamNames is a set : typedef set<string> StrSet;
stVecPair is a pair matching m_teams : typedef pair<string, vector<Person*> > stVecPair;
Full Error
error: no matching function for call to 'transform(std::map<std::basic_string<char>,
std::vector<Person*> >::const_iterator, std::map<std::basic_string<char>,
std::vector<Person*> >::const_iterator, std::insert_iterator<std::set<std::basic_string<char> > >,
RaceAnalyzer::teams() const::<lambda(RaceAnalyzer::stVecPair&)>)
As I commented, you've forgotten -std=c++11 option >o<
How to generate fusion::vector from mpl::vector?
How to generate mpl::vector from fusion::vector?
BOOST_MPL_ASSERT((is_same<
fusion::vector<int, char>,
generate_fusion_vector<mpl::vector<int, char> >::type >));
BOOST_MPL_ASSERT((is_same<
mpl::vector<int, char>,
generate_mpl_vector<fusion::vector<int, char> >::type >));
I need generate_fusion_vector and generate_mpl_vector metafunctions.
I can write my own metafunctions, but i suspect that they already exist.
I had an experience of generating fusion::map with help result_of::as_map before, but in current boost(trunk, 1.39 also) such error occur:
D:\Libraries\boost_trunk\boost/fusion/sequence/intrinsic/size.hpp(56) : error C2903: 'apply' : symbol is neither a class template nor a function template
D:\Libraries\boost_trunk\boost/fusion/container/vector/convert.hpp(23) : see reference to class template instantiation 'boost::fusion::result_of::size' being compiled
with
[
Sequence=boost::mpl::vector
]
temp.cpp(71) : see reference to class template instantiation 'boost::fusion::result_of::as_vector' being compiled
I don't understand what is going on?
As fusion accepts mpl types as arguments to functions you could try this:
BOOST_MPL_ASSERT((is_same<
fusion::vector<int, char>,
fusion::result_of::as_vector<mpl::vector<int, char> >::type >));
Edit:
I think the reason this isn't working for you is that you have to include certain header files to enable mpl compatibility in fusion.
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/include/mpl.hpp>
I don't know if you're still doing char,int but I ran into the same error and my problem was that I tried to make a length 11 vector, but FUSION_MAX_VECTOR_SIZE was 10.