Standard Template Library, Vectors and Syntax Errors - c++

This is my first time trying to incorporate STL into my code and I just have a few simple syntax questions I can't seem to figure out.
So I have created a vector of pointers:
std::vector<event_tracking*> track[10];
and within a loop in the main program I want to call
track[nfd] = new event_tracking(pfd[nfd].fd, initial_requests);
but this line gives the error
error: no match for 'operator=' in '((Pds::MyXtcMonitorServer*)this)->Pds::MyXtcMonitorServer::track[nfd] = (((event_tracking*)operator new(12u)), (<anonymous>->event_tracking::event_tracking(((Pds::MyXtcMonitorServer*)this)->Pds::MyXtcMonitorServer::pfd[nfd].pollfd::fd, ((Pds::MyXtcMonitorServer*)this)->Pds::MyXtcMonitorServer::initial_requests), <anonymous>))'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/vector.tcc:133: note: candidates are: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = event_tracking*, _Alloc = std::allocator<event_tracking*>]
and later on I want to call a function of my class like:
char* p = track[j]->receive_datagram();
But I get the error
error: base operand of '->' has non-pointer type 'std::vector<event_tracking*, std::allocator<event_tracking*> >'
and then I try to call delete like:
delete track[j];
and get the error:
error: type 'class std::vector<event_tracking*, std::allocator<event_tracking*> >' argument given to 'delete', expected pointer
I am really confused because I thought the way to call a function in a class when pointers are involved was by using the -> and I don't understand why that doesn't work here. I also don't understand why the [ ] aren't being used correctly to reference a specific element in the vector. If someone could please explain where my syntax errors are here and why they are arising that would be great! thank you

std::vector<event_tracking*> track[10];
This doesn't create a vector of 10 pointers. It creates an array of 10 empty vectors of pointers. To create a single vector of 10 pointers, use parentheses instead of square brackets.
std::vector<event_tracking*> track(10);

Related

Overriding operators/begin/end of a custom Array class

For an exercise we have to implement an array with custom bounds in various different languages, and one of them happens to be c++. Unfortunately i have never had to deal with c++ and am now struggling to get it done. I believe i have the right "core" of the header finished. The idea is that the user specifies bounds in a template and the class fakes this with help of an inner array. We were specifically told to overwrite the [] operator and implement begin() and end() functions. I am currently stuck at the visual studio debugger saying the following:
Error C2228 left of '.end' must have class/struct/union
The gcc compiler is saying:
In file included from Aufgabe1.test.cpp:2:
array.h: In instantiation of 'typename std::__cxx11::list<T>::iterator Array<T, L, H>::begin() [with T = int; int L = -2; int H = 1; typename std::__cxx11::list<T>::iterator = std::_List_iterator<int>]':
Aufgabe1.test.cpp:16:15: required from here
array.h:29:25: error: request for member 'begin' in '((Array<int, -2, 1>*)this)->Array<int, -2, 1>::innerArray', which is of non-class type 'int [4]'
return innerArray.begin;
~~~~~~~~~~~^~~~~
array.h: In instantiation of 'typename std::__cxx11::list<T>::iterator Array<T, L, H>::end() [with T = int; int L = -2; int H = 1; typename std::__cxx11::list<T>::iterator = std::_List_iterator<int>]':
Aufgabe1.test.cpp:16:15: required from here
array.h:33:25: error: request for member 'end' in '((Array<int, -2, 1>*)this)->Array<int, -2, 1>::innerArray', which is of non-class type 'int [4]'
return innerArray.end;
~~~~~~~~~~~^~~
Simply put i have no way of continuing from here since searching for these errors bring no clarification for someone who worked primarily with java so far. How can i solve thse issues and is my implementation of this Array otherwise correct ?
EDIT:
Had to remove the code
The first error message you mention explains the problem fairly well:
Error C2228 left of '.end' must have class/struct/union
The second group of messages tells you where this occurs, specifically when you try to use innerArray.end. The thing to the left of ".end" is innerArray, which is not declared as a class, struct, or union. (It's an array of T.)
So this comes down to the fact that (C-style) arrays do not have member functions. If you need an "end" function, maybe you should look into std::array, which wraps C-style arrays in a class. (If the requirement is to overwrite certain functions instead of implement them, this is the "array" your instructor likely had in mind.)

error: unitialized member with const type c++

I am writing a program that passes around a struct type that I don't want to be modified. This struct has two const members, and looks as follows:
struct system_s {
std::string name;
std::string pkg;
char *const start_cmd[10];
char *const end_cmd[10];
bool ros;
bool equals(const system_s &cmp);
};
The struct is being stored in a map with the following format. It is a class member:
std::map<std::string, system_s> sys_map;
There is another temporary map. Think of sys_map as a cache if you prefer. But really you don't have to worry about how it is being used for the sake of this question. sys_map is being called to add a system to the temporary map as follows. It is in a class method:
add_system(sys_map[msg->system]); (*)
This function has the following definition. It is a class method:
int add_system(const system_s &sys);
When (*) is called, I get the following error:
system.h: In instantiation of ?std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = system_s; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, system_s> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = system_s; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]?:
/tc_manager_node.cpp:74:41: required from here
/system.h:26:8: error: uninitialized member ?system_s::start_cmd? with ?const? type ?char* const [10]? [-fpermissive]
struct system_s {
^
system.h:26:8: error: uninitialized member ?system_s::end_cmd? with ?const? type ?char* const [10]? [-fpermissive]
In file included from /usr/include/c++/4.8/map:61:0,
from /opt/ros/indigo/include/ros/console.h:42,
from /opt/ros/indigo/include/ros/ros.h:40,
from
/tc_manager_node.cpp:2:
/usr/include/c++/4.8/bits/stl_map.h:469:59: note: synthesized method ?system_s::system_s()? first required here
__i = insert(__i, value_type(__k, mapped_type()));
Why is this member of type system_s 'uninitialized'? It presumably stored already initialized in sys_map. Does it have something to do with passing the system_s as a reference in int add_system(const system_s &sys)?
The operator[] of map (which you invoke with sys_map[msg->system]) has the possibility of creating a new entry if the map entry is not found. The new entry is default-constructed, but your class is not default-constructible.
To fix this, don't use [] on the map. Instead use find to find the entry you are looking for.
As #Greg Kikola said, const members must be initialized. Check here on how to do that with initializer lists (Not to be confused with std::initializer_list): http://en.cppreference.com/w/cpp/language/initializer_list
The position of the const with pointers can sometimes be confusing. X * const p indicates:
“p is a const pointer to an X that is non-const”: you can’t change the pointer p itself, but you can change the X object via p. [source]
This means that the address a system_s is created with can never be changed. Which is bad since you're not constructor-initializing start_cmd or end_cmd this means that none of the 10 pointers can be assigned a valid address. They start with an uninitialized addresses and can never be assigned anything else.
EDIT:
This post is tagged: c++03. There is no straight forward way to initialize arrays in C++03. You can look at this question for some workarounds: Initializing a member array in constructor initializer If you have the ability to go with c++11 you can use List Initialization.

using comparing function

I have this function
std::vector <std::vector <int> > puddles;
std::set <int> is_checked;
size_t M, N;
bool v_compare(int a, int b){
return puddles[(a-a%M)/M][a%M] < puddles[(b-b%M)/M][b%M];
}
and I want to find the set element which corresponds to the minimal value in puddles (I use i*M+j as a key in the set). So I am trying to use my function as a predicate for min_element
close(*std::min_element(is_checked.begin(), is_checked.end(), v_compare));
but I got this error
:113:82: error: no matching function for call to 'min_element(std::set<int>::iterator, std::set<int>::iterator, <unresolved overloaded function type>)'
:113:82: note: candidates are:
/usr/include/c++/4.6/bits/stl_algo.h:6173:5: note: template<class _FIter> _FIter std::min_element(_FIter, _FIter)
/usr/include/c++/4.6/bits/stl_algo.h:6201:5: note: _FIter std::min_element(_FIter, _FIter, _Compare) [with _FIter = std::_Rb_tree_const_iterator<int>, _Compare = bool (TFlood::*)(int, int)]
/usr/include/c++/4.6/bits/stl_algo.h:6201:5: note: no known conversion for argument 3 from '<unresolved overloaded function type>' to 'bool (TFlood::*)(int, int)'
There is a difference between a pointer to function and a pointer to member function. A class member which is not static gets you a pointer to member function. But std::min_element only accepts a pointer to function or other callable type, and a pointer to member function doesn't qualify since it can't be called without a pointer or reference to a class object. And as you found, if you try making the function a static member, then it can't get at the member M. (Maybe puddles too, if that's also a member.)
It looks like you're using g++ 4.6, which supports lambdas. So the easiest solution is:
close(*std::min_element(is_checked.begin(), is_checked.end(),
[this](int a, int b) { return puddles[a/M][a%M] < puddles[b/M][b%M]; }));
(I got rid of the subtractions, since division of integer types always rounds toward zero, so (a-(a%M))/M is always the same result as a/M.) Make sure you use the -std=c++0x compiler flag. The lambda magic takes care of "capturing" the this pointer for later use by the comparison object.

Use of C++ templates with dynamic binding class

In the past I have used both templates and dynamic binding in C++, however recently I attempted to use them together and found that it was impossible to compile.
What I am trying to do is something like this:
std::map<MyClass, unsigned int> mymap;
Where MyClass happens to be a class utilizing dynamic memory binding. After a few hours of searching I am given the impression that this causes implications which I still can't resolve, so I was hoping for some guidance on the issue and how it can be resolved.
My final goal is to be able to do something like this:
std::vector<MyClass> MyClassPool;
//fill the vector with MyClass objects...
for(usigned int i=0 ; i<MyClassPool.size() ; i++)
{
mymap[ MyClassPool[i] ] = i;
}
I have tried using pointers in various ways but it's not working and I fail to see what can be done.
I get the following errors with the above:
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h: In member function `bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Instance]':
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_map.h:338: instantiated from `_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = Instance, _Tp = float, _Compare = std::less<Instance>, _Alloc = std::allocator<std::pair<const Instance, float> >]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:227: error: no match for 'operator<' in '__x < __y'
That compile error means you have no operator < defined for Instance. map needs to be able to sort keys and needs this function. If you'd rather not define operator <, you need to provide a comparison function as a third template parameter for map, i.e. std::map<Instance, float, compare_instances>.
... Come to think of it, you're sure you want Instance as the key and float as the data, and not the other way around? I.e. you're searching in the map for an Instance to get a float in return?
You don't provide operator< for MyClass. It is required by std::map. You have two options: provide a comparator as the third template argument to map OR implement the operator in MyClass.
This has nothing to do with "dynamic binding" (which is not what is meant here anyway). Your class needs to have an order to be put into a map. It needs operator<.

Is there an implicit template<typename T>operator<<(const ostream&,T)?

I have a class I've written, meant to represent vectors (in the linear algebra sense). I just started writing it so it isn't finished, but i've pasted it and some test code here
I'm not really sure what's going on. I was going to write an overloaded operator<< for testing in a second, so I went ahead and put it in my main function (so I could use compiler errors to make sure I'd written it properly).
What does this warning mean? why it is looking at the address of v? I tried removing the parentheses from v, and I end up with this, a bunch of horrible template errors:
`
In function 'typename boost::range_const_iterator<C>::type boost::range_detail::boost_range_begin(const C&) [with C = vect<float, 3u>]':
/usr/local/include/boost/range/begin.hpp:164: instantiated from 'typename boost::range_const_iterator<C>::type boost::begin(const T&) [with T = vect<float, 3u>]'
prelude/more_stdlib_ostreaming.hpp:64: instantiated from 'void more_stdlib_ostreaming_detail::print_range(std::basic_ostream<_CharT, _Traits>&, const Range&) [with C = char, Tr = std::char_traits<char>, Range = vect<float, 3u>]'
prelude/more_stdlib_ostreaming.hpp:76: instantiated from 'typename more_stdlib_ostreaming_detail::snd<typename R::iterator, std::basic_ostream<_CharT, _Traits>&>::type operator<<(std::basic_ostream<_CharT, _Traits>&, const R&) [with C = char, Tr = std::char_traits<char>, R = vect3f]'
t.cpp:42: instantiated from here
Line 45: error: 'const class vect<float, 3u>' has no member named 'begin'`
I can sort of see whats going on here, tho. It looks like it is somehow using boost's range for and trying to iterate over my container, and it is failing because I haven't defined begin() and end(). The same thing happens if I instantiate v using v(some_float) rather than without the parens.
So, two questions:
Why is v() behaving differently than v? I thought that declaring a object without parens always calls the default ctor anyway, and explicitly calling the default ctor made no difference?
What is codepad's compiler (gcc 4.1.2) doing here? Does it have a template that automatically tries to generate an appropriate operator<
Also, feel free to tell me anything else I'm doing stupid/wrong/bad style here (besides rolling my own matrix math library for fun, which I know is unnecessary. I'm doing it as an exercise)
First of all, vect3f v(); declares a function (named v), taking no parameters and returning vect3f. And the operator<< that is being called is called for this function pointer (which is implicitly converted to bool, because there's no overload for function pointers).
vect3f v; is the correct way of creating default-constructed object.
And no, compiler won't try to generate ostream& operator<<(ostream& /* ... */) for you. There are however many overloads for all fundamental types and even some other types (such as std::string).
You can check all basic overloads here.