I'm using boost::bimap to map integers to strings:
typedef boost::bimap<int, std::string> ParamIDStrings;
typedef ParamIDStrings::value_type id_pair;
extern const ParamIDStrings paramIDStrings;
I'm trying to create reference variables so I can write code like:
paramIDStringsByID.at(5);
// Instead of having to remember which side is which:
paramIDStrings.left.at(5);
But I'm having a hard time interpreting the Boost documentation, to understand of what type bimap::left is.
I tried:
// Compiler throws error: invalid use of template-name 'boost::bimaps::bimap' without an argument list
boost::bimaps::bimap::left ¶mIDStringsByID = paramIDStrings.left;
// Compiler throws error: 'paramIDStrings' does not name a type
paramIDStrings::left_map ¶mIDStringsByID = paramIDStrings.left;
// Compiler throws error: invalid initialization of reference of type boost::bimaps::bimap<int, std::__cxx11::basic_string<char> >::left_map
boost::bimaps::bimap<int,std::string>::left_map &cParamIDStringsByID = cParamIDStrings.left;
You can use auto & to let the compiler do the work for you.
If you want to know the type that gets deduced you can use one of the tricks from here to make the compiler tell you.
boost/bimap/bimap.hpp has a typedef for this: left_map and right_map. So you can do:
paramIDStrings::left_map ¶mIDStringsByID = paramIDStrings.left;
Related
I am trying to debug the existing code in our application written with C++,while I am trying to print a unique_pointer to a std:set of type unsigned long, I am facing a compilation error
error: 'class std::unique_ptr<std::set<long unsigned int> >' has no
member named 'size'
below is my code snippet which I am trying to print using cout.
auto current_list = std::make_unique<std::set<uint64_t>>();
std::cout << "Number of elements in current_list is : " << current_list.size();
I am new to unique_ptr, I had tried even with Iterator initialized with current_list.begin() but non of these helpers are associated with the variable current_list.
Please help me understand where I am missing.
Thanks,
Srini.
Smart pointers are mostly like pointers, you need -> to access member of pointee:
current_list->size()
Alternatively:
(*current_list).size()
or, for std::unique_ptr/std::shared_ptr:
current_list.get().size()
(and don't forget to check for nullptr before de-referencing it).
I have a simple header parser based on clang and I get the typedefs from some source.
struct _poire {
int g;
tomate rouge;
};
typedef struct _poire kudamono;
After parsing this I have a clang::TypedefDecl then I get the clang::QualType of the typedef with clang::TypedefDecl::getUnderlyingType()
With the QualType if I use the getAsString method I can find the "struct _poire" std::string. All this is Ok.
The problem is if I try to see if this type is a canonical type, with QualType::isCanonical(), it returns false.
So I try to get the canonical type with QualType::getCanonicalType().getAsString() and it returns the same string "struct _poire".
according to the clang reference on type http://clang.llvm.org/docs/InternalsManual.html#canonical-types , I thought that the isCanonical() should return
true when no typedef is involved.
So what are really canonical type?
After further investigations and a question in the clang mailing list, I think I have figured out what is a canonical type.
Firstly it 's important to not focus on the QualType in order to understand Canonical Type. Look this (code /pseudocode):
source file :
typedef struct _poire kudamono;
clang code :
QualType t = clang::TypedefDecl::getUnderlyingType()
t.getAsString() // "struct _poire"
t.isCanonical() // false
t.getTypePtr()->getTypeClassName() // ElaboredType
c = t.getCanonicalType()
c.getAsString() // "struct _poire"
c.isCanonical() // true
c.getTypePtr()->getTypeClassName() // RecordType
c and t are not the same QualType even if they have the same string representation.
QualType are used to associate qualifiers ("const", "volatile"...) with a clang type. There are a lot of Clang Types classes because clang needs to keep tracks of the user-specified types for diagnostics.( http://clang.llvm.org/docs/InternalsManual.html#the-type-class-and-its-subclasses and http://clang.llvm.org/doxygen/classclang_1_1Type.html )
The clang types used depends heavily on the syntaxic sugars or modifiers associated with the C/C++ types in the source file.
In the exemple above, the QualType t is associated with an ElaboratedType. This type allows to keep track of the type name as written in the source code. But the canonical QualType is associated with a RecordType.
Another example:
source file:
typedef struct _poire kudamono;
typedef kudamono tabemono;
clang code :
QualType t = clang::TypedefDecl::getUnderlyingType()
t.getAsString() // "kudamono"
t.isCanonical() // false
t.getTypePtr()->getTypeClassName() // TypedefType
c = t.getCanonicalType()
c.getAsString() // "struct _poire"
c.isCanonical() // true
c.getTypePtr()->getTypeClassName() // RecordType
Here we can see that the underlying type of the typedef is recorded as "kudamono" a TypedefType and not "struct _poire" an ElaboratedType.
The canonical type for the TypedefType "kudamono" is a RecordType "struct _poire".
Another examples that I have had from the clang mailing-list ( http://article.gmane.org/gmane.comp.compilers.clang.devel/38371/match=canonical+type ):
Consider:
int (x);
The type of x is not a BuiltinType; it's a ParenType whose canonical type is a BuiltinType. And given
struct X { int n; };
struct X x;
the type of x will probably be represented as an ElaboratedType whose canonical type is a RecordType.
So the canonical Type in clang are classes of types that are not associated with any syntaxic sugars or modifiers or typedef (like BuiltinType or RecordType). Other classes of types (like ParentType, TypedefType or ElaboratedType) are used to keep tracks of the user type for diagnostics (error message ...).
It seems that you have raised an interesting point. I have figured out something, but since I can't actually test my intuition right now, I can't be 100% sure. Anyway here is what I would do :
If I parse your code (with a little extension to declare a kudamono variable), here is what I can say from this:
struct _poire {
int g;
char rouge; // tomate is probably one of your classes so I just changed the type of the field.
};
typedef struct _poire kudamono;
int maFonction(){
kudamono une_poire;
return 0;
}
When the typedef is parsed, here is what is yielded :
-TypedefDecl 0x23b4620 <line:5:1, col:23> kudamono 'struct _poire':'struct _poire'
When I declare a variable of type kudamono, here is below its AST-dump :
-VarDecl 0x2048040 <col:2, col:11> une_poire 'kudamono':'struct _poire'
NB : You can get the AST Dump of your code with this command line, it can be really handy to understand how your code will be parsed :
clang -Xclang -ast-dump -std=c++11 -fsyntax-only test.cpp (just remove -std=c++11 if you want to compile a file_name.c file)
Now, from what I understand, I will make a comparaison between the VarDecl and the TypedefDecl :
1°) This VarDecl is named une_poire and has the type kudamono which is a typedef from the type struct _poire.
2°) This TypedefDecl is named kudamono and has the type struct _poire which is a typedef from the type struct _poire
So, the weird part is right here. struct _poire is considered as typedef from struct _poire.
You'll note that I tried to make a typedef with a usual type :
typedef int numbers;
And this time, AST-dump yields :
TypedefDecl 0x25d9680 <line:7:1, col:13> numbers 'int', so I guess the parser may have some troubles with handmade types (typically structs).
I can see one dirty way to know if your type is canonical or not (without getting false positives or false negatives) :
Check that the QualType and the canonical QualType are not the same
I don't know if a simple '=' between Qualtype will make false positives or false negatives (as I can't test), but you can still compare the names of the types with strcmp
So, to sum up a little bit :
Your understanding of a canonical type is fine.
Clang seems to have some trouble with handmade types, but it should be fine with Typedef from usual types (such as typedef int int32_t).
When you want to know if a type is canonical or not, you can compare the name of the type and the name of the canonical type, but it's quite dirty. On usual type, isCanonical() works well.
I have a vector defined as:
std::vector<std::shared_ptr<Orders> > vOrders;
When adding to vOrders I want to add like:
vOrders.push_back(<std::shared_ptr<Orders> >([]() {
TimerForProcessingOrders _timerForProcessingOrders;
_timerForProcessingOrders.detach();
}));
but the compiler is giving me an error:
Expected expression: Expected '(' for function-style cast or type construction
It looks weird the < and > around std::shared_ptrbut removing it gives an error:
No matching conversion for functional-style cast from '<lambda >' to 'std::shared_ptr<Orders>'
What mistake am I making?
What this code does (in an ill formed way) is take the object constructed by the lambda, and store the lambda itself into the vector -- not an object of type shared_ptr<Order> which is what the vector requires.
but the compiler is giving me an error:
This is because the extra < > are completely invalid syntax, so the best the compiler can give you is "invalid expression".
It looks weird the < and > around std::shared_ptrbut removing it gives an error:
No matching conversion for functional-style cast from '<lambda >' to 'std::shared_ptr<Orders>'
Basically what you have here is shared_ptr<Orders>(/* .. Lambda .. */) -- and the compiler is saying that it has no idea how to turn the lambda into an Orders* to go into the shared_ptr.
What are you actually trying to accomplish here?
If you just want to transfer a pointer into the shared_ptr you can do something like
TimerForProcessingOrders _timerForProcessingOrders;
std::shared_ptr<Orders> ptr(_timerForProcessingOrders.detach());
vOrders.emplace_back(std::move(ptr));
no lambda is required.
What type is Orders? Actually, it doesn't really matter: the expression [](){ ... } certainly isn't of a type convertible to Orders*. ... and the angle brackets around the argument to push_back() a definitely wrong.
Did you mean to call the lambda expression?
vOrders.push_back(std::shared_ptr<Orders>([]() {
TimerForProcessingOrders _timerForProcessingOrders;
return _timerForProcessingOrders.detach();
})()
); // ^^ note these extra parenthesis
... but even that shouldn't work as the lambda expression doesn't return anything (hence the also added return).
Firstly, I'd suggest you follow Billy ONeals train of thought. But if you want to do it your way this is a SSCE of it.
There are two changes, this lambda returns an object and is executed, thereby returning.
#include <vector>
#include <memory>
#include <iostream>
struct Foo {
int val;
};
int main(int argc, char** argv) {
std::vector<std::shared_ptr<Foo> > v;
v.push_back([]() -> std::shared_ptr<Foo> { Foo f; f.val = 5; return std::make_shared<Foo>(f); }());
std::cout <<v[0]->val <<std::endl;
return 0;
}
I am interested in Judy Arrays and try to use it. But i had unable to do any useful thing using it. Every time it gives me casting errors.. Sample c++ code and the error given below.
#include "Judy.h"
#include <iostream>
using namespace std;
int main()
{
int Rc_int; // return code - integer
Word_t Rc_word; // return code - unsigned word
Word_t Index = 12, Index1 = 34, Index2 = 55, Nth;
Word_t PValue; // pointer to return value
//Pvoid_t PJLArray = NULL; // initialize JudyL array
Pvoid_t JudyArray = NULL;
char String[100];
PWord_t _PValue;
JSLI( JudyArray, _PValue, (uint8_t *) String);
return(0);
} // main()
This gives me the error
m.cpp: In function ‘int main()’:
m.cpp:19: error: invalid conversion from ‘long unsigned int**’ to ‘void**’
m.cpp:19: error: initializing argument 1 of ‘void** JudySLIns(void**, const uint8_t*, J_UDY_ERROR_STRUCT*)’
Please anyone help me to figure out what is the error what i'm doing..
Thanks
According to the documentation, you have the _PValue and JudyArray parameters reversed. Make your call look like this:
JSLI( _PValue, JudyArray, (uint8_t *) String);
Also, try not compiling it as C++ code. So far, your test uses no C++ features. I bet it will compile as C code. It looks like JudyArray relies on the fact that C will do certain kinds of implicit conversions between void * and other pointer types.
If this is the case, I'm not sure what to do about it. The error messages you're getting tell me that JSLI is a macro. In order to fix the error message you have in the comments on this answer, you'd have to reach inside the macro and add a typecast.
These kinds of implicit conversions are allowed in C because otherwise using malloc would always require ugly casts. C++ purposely disallows them because the semantics of new make the requirement that the result of malloc be cast to the correct type unimportant.
I don't think this library can be used effectively in C++ for this reason.
It seems that, you pass JudySLIns(void**, const uint8_t*, J_UDY_ERROR_STRUCT*) a wrong parameter, the first one, you'b better check it!
For integer keys there is a C++ wrapper at http://judyhash.sourceforge.net/
I have declared my array like this:
FT_Interface<4096> *to_make_ft[3] = { /* initialization with existing objects */ };
my interface is declared like this:
template<cyg_ucount32 S, int N>
class FT_Thread {
FT_Thread(FT_Interface<S> *entry[N]){}
};
And i call it (as expected with):
FT_Thread<4096, 3> ft(to_make_ft);
Yet it complains that the pointer has decayed.
ecos/install/include/ft/thread.hxx:70: error: incompatible types in assignment of ‘FT_Interface<4096u>**’ to ‘FT_Interface<4096u>* [3]’
Is there any way to prevent this from happening?
You need
FT_Thread(FT_Interface<S>* (&entry)[N]){}
// note these ^^-----^
With that, you get a reference to the array.
Edit: Of course, if you want a pointer to the array, you can have just that:
FT_Thread(FT_Interface<S>* (*entry)[N]){}
Though you need to call it with FT_Thread<4096,3> ft(&to_make_ft).
I don't know if this is right, but try changing
FT_Thread(FT_Interface<S> *entry[N]){}
to
FT_Thread(FT_Interface<S> (*entry[N])){}
I have a feeling that the compiler thinks that the * refers to the FT_Interface rather than the entry.