In boost multiindex example complex_structs, it use one key in the car_manufacturer struct for car_table.
If car_manufacturer have been modify to have 2 ID
struct car_manufacturer {
std::string name;
int cm_code;
car_manufacturer(const std::string& name_, const int& cm_code_):name(name_), cm_code(cm_code_){}
};
What will be the key_from_key struct looks like? Have try to add another KeyExtractor or use composite index inside key_from_key, but still cannot compile.
Please help on this. Thanks.
After some trying, my compile error is actually cause by using find() without boost::make_tuple.
Can use back the same key_from_key struct. Key1Extrator will be composite key of name and cm_code.
Related
Problem: I have a class of parameters which I'm passing around as const Some_Class& param because these parameters aren't changing. I need to pass these parameters to external library (GSL) which is accepting void* param. I can't cast from const& to void*, except with using const_cast. I heared that const_cast is not generally right solution, is this the correct use case for it?
My solution: As a solution I'm now using wrapper structure
struct wrapper{const Some_class& param;};
void gsl_func(void* param){
const Some_class& my_param = static_cast<wrapper*>(param)->param;
}
void my_func(const Some_class& my_param){
wrapper my_wrapper = {my_param};
gsl_func(&my_wrapper);
}
Which doesn't seems like the most elegant solution as I have to do this before every call to GSL. Is there some standardize way how to do this better?
I want to specify that a certain type reported by Boost TypeIndex boost::typeindex::type_id<T>().pretty_name() would yield a specific name.
The problem I want to solve is that, as reported in other places, there is a particular case that is confusing, that is the std::string type (or alias) gets reported as std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >.
(I understand the reason for this, std::string is an alias. I just want to override the reported string in this particular case.)
I followed the instructions here http://www.boost.org/doc/libs/1_59_0/doc/html/boost_typeindex/making_a_custom_type_index.html and the beginning of the custom code looks like this:
namespace my_namespace { namespace detail {
template <class T> struct typenum;
template <> struct typenum<void>{ enum {value = 0}; };
template <> struct typenum<std::string>{ enum {value = 1}; };
struct my_typeinfo {const char* const type_;};
const my_typeinfo infos[2] = {
{"void"}, {"std::string"}
};
...
...
But at the end, the most I can do is to replace one type reporting by another, instead of just amending one case.
One light weight solution could be to specialize boost::typeindex::stl_type_index (the output type of type_id<std::string>()) but by then the actual static information of the class is lost. (there is no class to specialize.)
But this cannot be done without a full specialization of typeid<std::string> which seems to difficult to do.
Is there a workaround for this? I would prefer a solution within Boost.Typeindex rather than runtime string replacement.
This is a very dirty way I found but it is not perfect and can create other problems down the road.
struct std_string{}; // dummy replacement class name
namespace boost{
namespace typeindex{
template<> boost::typeindex::stl_type_index type_id<std::string>() noexcept{
return type_id<std_string>(); // will report "std_string", ugly, but better than `std::__cxx11::basic_string<...>`
}
}}
The documentation for Boost multiindex containers seem to indicate that I can use it as a set after declaring an index to iterate over. So I was wondering if it is possible to hide the boost implementation and return an iterator masqueraded as an iterator to an std::set
Ex: Header
typedef multi_index_container<
Employee,
indexed_by<
ordered_non_unique<
composite_key<
Employee,
member<Employee, int, &Employee::id>,
member<Employee, int, &Employee::salary>
>
>
> > EmployeeSet;
const std::set<Employee>::iterator getEmployees();
static EmployeeSet employeeSet;
Test.cc:
const std::set<Test::Employee>::iterator getEmployees(){
std::pair<EmployeeSet::iterator, EmployeeSet::iterator> by_id =
employeeSet.equal_range(id);
return by_id.first;
}
Is it possible to do something like this? and How?
No, you can't. The EmployeeSet you have defined works like a std::set (a std::multiset, actually), but it is not one. The iterator types of these unrelated containers are different and you can't pass one as the other.
Maybe you can reconsider why you need to pass an iterator to an index of a multi_index_container as a std::set::iterator.
I am really stuck here with a seemingly trivial problem in Go:
I have a Golang microservice, which outputs data in json format. Let's say I have a simple struct with json tags for this result:
type Result struct {
Name string `json:"name"`
Age int `json:"age"`
}
In the code part where the data is actually pulled out of the database, I have a quite similar struct, like this:
type ResultBackend struct {
Name string `bson:"fullName"`
Age int `bson:"age"`
}
The struct fields are similar, except the different tags. I would like to keep things simple, and return just one struct from the backend service (ResultBackend), which can then be send as a JSON response, like this:
func process() Result {
var result ResultBackend
... do a MongoDB query here and store results in result variable ...
return result
}
This certainly would not work, because we have two different structs here.
Of course one solution would be to embed both tags in one struct like so:
type Result struct {
Name string `json:"name" bson:"fullName"`
Age int `json:"age bson:"age"`
}
and then use this struct in the main code and the "process" function.
This works, but this seems like "poisoning" the Result struct of the main code with the bson tags. What, for instance, if the backend result is a XML file? I'd have to add xml tags to the struct as well. Or maybe someday tags some very obsure database adapter.
This doesn't seem to be the cleanest approach in my eyes. I'd rather have a clean Result struct in the main code, and simply to a conversion from one struct to another.
Is there any easy way doing that, or do I really have to copy all the fields of a ResultBackend struct to a new Result struct and return that? Or I am trying to over-simplify my code here? :)
Cheers!
What I'd do is create a separate type for every "serialisation format" if you will. This approach has several advantages:
Your concerns are separated.
JSON un/marshalling doesn't interfere with BSON/XML, so you can add any kind of additional struct fields (like xml.Name for example).
You can actually create several such types for different APIs that need different parameters.
The only disadvantage I see is that it's more code and even more code to move data between those. Ultimately it's up to you and your application design. If you're sure that your JSON/BSON will stay the same, you can use one type. Otherwise, I'd recommend specialisation.
To those who want to add bson tags in golang struct, here is a tool which can be helpful. I have spent a whole day searching for this and I want others to save their valuable time.
You can convert the following struct
type Result struct {
Name string `json:"name"`
Age int `json:"age"`
}
into
type Result struct {
Name string `json:"name" bson:"fullName"`
Age int `json:"age bson:"age"`
}
With this tool, you can not only add bson tags but also
XML tags,
Define validation and scope
Format tag values
Apply transformation
skip unexported fields.
Go Modify Tags: https://github.com/fatih/gomodifytags
Cheers,
This question is out of pure curiosity. How does Cocoa define the id type? Is it just a typedef for a void *? Also, if you know which header file it is defined in, I would be interested in taking a look.
Hold down the command key and double click on any highlighted term to jump to its definition.
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...);
It is delcared in /usr/include/objc/objc.h (on Leopard) as follows:
typedef struct objc_object {
Class isa;
} *id;
Which means it is not void * at all, but rather a pointer to a struct that contains a single member, pointing at the class definition. Interesting indeed.
I remember when I was just getting into C and learning that Objective-C was initially implemented as just a preprocessor layer on top of C. It isn't quite like that anymore.
The best reading on the topic I've found:
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html
in objc.h
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
To find out on your own, in XCode, right click id -- or any other type -- and select Jump to definition. It's interesting to note the similarities to other C/C++ based object systems; an object pointer -- an id -- points to a struct that starts with a point to shared class information. I many C++ implementations, that would be the virtual function table, as it would be with Microsoft's COM. In Cocoa, the particulars of objc_class aren't revealed to us in the header file.
The id type is generally declared like:
typedef struct objc_object *id;
This is critical for Objective-C++ where the type is part of a mangled function name.
You can take a look in /usr/include/objc/objc.h
You can refer the doc here : http://opensource.apple.com/source/objc4/objc4-437/runtime/objc.h
Hope this will do a favor for you