I have wrapper classes for all STL containers. And I want to see values contained in one of the map while debugging my code base on gdb. I already have .gdbinit with all stl-views. And currently my gdb is recognizing all stl commands like pmap, pvector etc. but when I provide my wrapper map (or any other container) object as an argument to stl commands I am getting following error.
(gdb) pmap wrapperMapObj
Invalid type combination in equality test.
How can I see values in wrapper objects?
I already have .gdbinit with all stl-views
STL-views are so last century. If you are using GDB-7.x, the new python pretty printers will likely provide much better user experience.
but when I provide my wrapper map
Since you haven't explained what your "wrapper map" is, how could we possibly answer your question about it?
Related
I have good command over c++ language.I am interested in creating code which generates the object dynamically for which no schema has already been defined in code.First of all, is it possible to do so in c++? If yes, please anyone would guide me how to do it?
For example,
<name>android</name>
<count>5</count>
<version>4.4.4</version>
If this is given in file(.xml), the automatic object should be created and I should be able to access it.
TempObj.name, TempObj.count and TempObj.version etc..
No, you cannot do this at runtime in C++. Types have to be known at compile time in C++.
You can do code generation, i.e. read XML, generate C++, and compile. Or you can use a slightly different syntax (and much slower performance) to access the methods, basically:
typedef std::map<std::string, std::string> Object;
Object obj = load("whatever.xml");
assert(obj["name"] == "android");
But to do exactly what you've asked will require a different language. Tons of choices: Python and Lua are two that easily integrate with a C++ application directly, if you want that.
Using a hash table would solve your problem. in C++, the STL (standard template library) provides std::unordered_map<>
You should use that to solve your problem.
std::unordered_map<std::string, std::string> hm
The API is nice, where you can insert and change elements by using the [] operator.
hm["name"] = "android"
hm["count"] = "5";
hm["version"] = "4.4.4";
If you need dynamic types, you could probably use templates.
You may be wondering why you would use an ordered or an unordered map in C++. With an ordered map, all elements are able to iterated in the order they were inserted, whereas an unordered map the order in which you will access them is random based on the hashed value.
I want to be able to debug objective-c++ code which contains instances of a c++ class quickly.
With objective-c classes, I can simply implement description to return a human readable string, and then when I po var in lldb I immediately know anything I need to know about the instance.
Is there any way I can achieve this for c++ classes used from objective-c++ code as well?
The easiest way to do this in lldb is to add a "summary formatter" for the C++ class. This web page gives a pretty good intro to how to do this:
http://lldb.llvm.org/varformats.html
Look for the section on "Type Summaries".
If the class's ivar values directly contain all you want to see about the class, then you can cons up a summary string that will present the ivar values and any markup text you think desirable without having to use the LLDB Python API's to take apart the class. If you need to do more work to produce your summary, you will have to use the Python API's as trojanfoe suggests.
For instance, if you wrote a "description" method for your C++ class, you could use LLDB's Python API's to call that method and return the string as the summary. But if possible, it is preferable to produce the summary from static knowledge of the class, since running code in the debugger is generally slower than inspecting memory.
There is also information on how to use the LLDB Python interface to produce summaries on the same page.
The Type Summaries you write can be added in your .lldbinit file, and the summary values will show up when you print an instance of the class in lldb, and also in the summary column in the Locals view in Xcode.
Note, you can do this for any type, C, C++ or ObjC. Many of the C++ STL classes and the more common Foundation classes have built-in summaries that use the same mechanism. That, and not the description method, is how lldb produces the one-line summaries you see in Xcode.
I'd like some advice on how to check for the correctness of the parameters I receive.
The checking is going to be done in C++, so if there's a good solution using Boost.Python (preferably) or the C API, please tell me about that. Otherwise, tell me what attributes the object should have to ensure that it meets the criteria.
So...
How do you check that an object is a function?
How do you check that an object is a bound method?
How do you check that an object is a class object?
How do you check that a class object is a child of another class?
When in doubt just work out how you would get the required effect by calling the usual Python builtins and translate it to C/C++. I'll just answer for Python, for C you would look up the global such as 'callable' and then call it like any other Python function.
Why would you care about it being a function rather than any other sort of callable? If you want you can find out if it is callable by using the builtin callable(f) but of course that won't tell you which arguments you need to pass when calling it. The best thing here is usually just to call it and see what happens.
isinstance(f, types.MethodType) but that won't help if it's a method of a builtin. Since there's no difference in how you call a function or a bound method you probably just want to check if it is callable as above.
isinstance(someclass, type) Note that this will include builtin types.
issubclass(someclass, baseclass)
I have two unconventional recommendations for you:
1) Don't check. The Python culture is to simply use objects as you need to, and if it doesn't work, then an exception will occur. Checking ahead of time adds overhead, and potentially limits how people can use your code because you're checking more strictly than you need to.
2) Don't check in C++. When combining Python and C (or C++), I recommend only doing things in C++ that need to be done there. Everything else should be done in Python. So check your parameters in a Python wrapper function, and then call an unchecked C++ entry point.
I have some C++ methods that have std::set<std::string> as argument or return value.
I would like to map this to a Python frozenset (or regular set) but there does not seem to be a straightforward way to do this.
Does anyone know how one may accomplish this task.
Or you can use std::map<YourType, int> instead of std::set<YourType>, the value can be for example 0. std::map has the same insert/search time complexity as std::set, it also keeps the keys ordered, it will only bloat the memory a little. Then you can use map indexing suite and in python you can hide the difference in some wrapper class if needed. The disanvantage is that you have to modify your existing c++ code a little bit.
Unfortunately, the standard indexing_suite from Boost.Python does not support std::set. There is a indexing_suite v2, that works on all stl containers. (http://mail.python.org/pipermail/cplusplus-sig/2009-July/014704.html)
It may not have made it to the official distribution, but you can find it by asking around.
(http://mail.python.org/pipermail/cplusplus-sig/2009-July/014691.html)
I found it to be harder to use then the original indexing_suite, but it might fit your needs.
If that does not work, you can just manually wrap std::set<std::string> like you would any other class. This will get you a std::set<std::string> into python, where you can turn it into a python set fairly easily.
I think that both of those are more work then is called for though. Here is what I would do:
First, wrap the function in C++ with one that has the same signature, but stuffs the returned data in to a std::vector<std::string> instead of a std::set<std::string>. expose that function rather then the original
Now you have the data in python.
Second, wrap the c++ function in python function that takes the data in that std::vector<std::string> and stuffs it into a python set.
Yes, this is rather silly from a design aesthetics point of view, and not the most performant code in the world, but is gets you to where you are going with a minimum of code, and it is fairly robust.
I'd like to generate a number of objects (in C++) based on the amount/number the user enters.
Now I've somewhere heard that it has to be done using pointer tricks, creating a pointer to an array of the Object type required, and then dynamically increasing the size of array ( at runtime ).
Isn't there a workaround of directly using names like
Object1, Object2..... ObjectX
instead of having
Classname *Object[]
and then using the array index to get the object ?
In either case, it'd be great if someone could clarify on the issue.
Thanks !
If you want dynamically-sized array, then use std::vector. You won't be able to resize a built-in array.
If you want to be able to get an object by string name, then you should use std::map, it has an indexer:
std::map<string, Classname> myMap;
myMap["Object1"] = Classname();
Classname newClassname = myMap["Object1"];
So far no-one has explained why your thinking is flawed. C++ is a compiled language, and it goes to great lengths to turn the source program into efficient machine code. For this reason, the names you give variables are available to the program only at compile time, when you turn it from source into an executable file. Afterwards, when you want to create objects dynamically, those kinds of information are no longer available. The program only knows about the machine addresses where operands to machine instructions are located.
No, there isn't. Moreover, you don't need to; use std::vector.
When I began programming 9 years ago I asked myself the same question. The answer is: you can't.
You can indeed use an array and resize it dynamically, however using an stl vector is much easier (once you learn how to use it).
You can not do that because C++ doesn't have an "environment" (reflection) where variables (and metadata) can reside. Moreover, in C++ all variable names are vanished when the code is compiled.
A way to achieve the effect you want is to use a Map where the keys are strings.