I am developing GUI application via wxWidgets. It has 2 parts: GUI part and "Logic" part. I want to have Logic part totally independent on wxWidgets. But one component in the GUI returning wxVariant and I need to use it in the Logic part.
So I am looking for a way to "convert" wxVariant to boost::variant
wxVariant works like this:
wxVariant v("37");
int i = v.GetInteger(); //i==37
So I am thinking something like
string s = methodReturningWxVariant().GetString();
boost::variant bV(s);
//later in code e.g
bV.GetInt();
bV.GetBool();
Is it possible to use boost::Variant (or boost::Any) like this?
You can probably use boost::variant with some changes. To start with, you need to tell boost::variant which types it will be storing:
boost::variant<int, string, bool> v;
Since you probably will be using this type in a few places, you will probably want to create an alias for it. i.e.
typedef boost::variant<int, string, bool> myvar;
then you can use myvar directly:
myvar x = "hello";
myvar y = 20;
myvar z = false;
to retrieve values:
string s = boost::get<string>(x);
int i = boost::get<int>(y);
bool b = boost::get<bool>(z);
If you attempt to get a different type than is stored in the variant, it will throw an exception.
You can query the variant's type with the which() member function. It will return a 0-based index to the type the variant is currently holding.
switch (x.which()) {
case 0: // it's an int
case 1: // it's a string
case 2: // it's a bool
}
Simple answer? No. You cannot convert via strings, this induces a loss of information and boost::variant does not automatically attempt to parse strings.
I don’t know whether wxVariant offers an explicit conversion – in general, it may be difficult to convert to boost::variant without testing for special cases.
boost::variant (please don't capitalize 'v') works another way: you can only get back what you put inside. Think about it as a type-safe(r) union.
Checking documenation and tutorial also won't hurt.
Boost.Any library doesn't differ from Boost.Variant in this respect (what you put is what you get :) ), but boost::any is unbounded: you can store value of any type in boost::any, but in boost::variant you can only store what was declared by variant's template parameters.
boost::variant does not do conversion for you. There are other separate means to convert a string to an integer, such as strtol(), sscanf(), boost::lexical_cast<>()...
Related
I have an Apache arrow array that is created by reading a file.
std::shared_ptr<arrow::Array> array;
PARQUET_THROW_NOT_OK(reader->ReadColumn(0, &array));
Is there a way to convert it to std::vector or any other native array type in C++?
You can use std::static_pointer_cast to cast the arrow::Array to, for example, an arrow::DoubleArray if the array contains doubles, and then use the Value function to get the value at a particular index. For example:
auto arrow_double_array = std::static_pointer_cast<arrow::DoubleArray>(array);
std::vector<double> double_vector;
for (int64_t i = 0; i < array->length(); ++i)
{
double_vector.push_back(arrow_double_array->Value(i));
}
See the latter part of the ColumnarTableToVector function in this example:
https://arrow.apache.org/docs/cpp/examples/row_columnar_conversion.html. In that example, table->column(0)->chunk(0) is a std::shared_ptr<arrow::Array>.
To learn more, I found it useful to click on various parts of the inheritance diagram tree here: https://arrow.apache.org/docs/cpp/classarrow_1_1_flat_array.html. For example, strings in an arrow::StringArray are accessed using a GetString function instead of a Value function.
This is just what I've pieced together from these links, johnathan's comment above, and playing around with a small example myself, so I'm not sure if this is the best way, as I'm quite new to this.
I want to store arbitrary parameter data for some robotics software. I'll give some examples to clarify what I want to do:
Say, for example, I want to store variables "quadruped.gait.step_height = 0.25" and "quadruped.gait.gait_type = "trot"" this should break down to something like
variable_map["quadruped"]["gait"]["step_height"] = 0.25;
or
variable_map["quadruped"]["gait"]["gait_type"] = "trot";
The code I currently have to handle this kind of thing (which works just fine if I know what the type of the variable is):
std::map<std::string, void* > var_map;
template <class X>
void set_variable(std::string key, X var)
{
var_map[key] = &var;
}
template <class X>
X get_variable(std::string key)
{
return *reinterpret_cast<X*>(var_map[key]);
}
this does the somewhat less clean looking task of storing each variable in:
variable_map["quadruped.gait.step_height"] = 0.25;
Which feels like a shoddy way of doing what I want. And I need to know the type of the variable ahead of time:
set_variable<bool>("quadruped.PID.workspace.active",true);
bool workspace_active = get_variable<bool>("quadruped.PID.workspace.active");
Ideally I'd like to handle this type of variable assignment in an XML reader or some kind of script-parsing format at startup.
I feel like this is a common need among software developers and I can't help but feel like I'm re-inventing the wheel on this problem. Is there a piece of open source code out there (preferably with a good license), or maybe just a simpler way of reading in a script:
quadruped.gait.gait_timing = [ 0 0.5 0 0.5 ]
quadruped.gait.step_height = 0.25
quadruped.gait.gait_type = "trot"
quadruped.PID.workspace.active = 1
and storing them as:
variable_map["quadruped"]["gait"]["gait_timing"] = (std::vector) % containing [ 0 0.5 0 0.5 ]
variable_map["quadruped"]["gait"]["step_height"] = (double) 0.25;
variable_map["quadruped"]["gait"]["gait_type"] = (std::string) "trot";
variable_map["quadruped"]["PID"]["workspace"]["active"] = (int) 1;
or maybe just storing them in any manner where I can retrieve them by name in my code such as in my previous example:
bool workspace_active = get_variable<bool>("quadruped.PID.workspace.active");
Thanks for your help. If you need any further clarification on any of the points I've made, I'll be monitoring this question closely.
Your problem is indeed a common problem. Therefore there exist a common solution, which is boost::variant that stores a variable of an arbitrary type.
The advantage is that it constructs the variant type based on all the potential types you consider (and provide as template parameters):
typedef boost::variant< int, std::string, double> vtype;
This approach permits to avoid common issues, like the nasty misaligned variables (see for example this SO question). It also enables some compile-time type checking, making sure that you don't use it accidentally types that are not foreseen.
vtype v1, v2;
v1 = "Hello";
v2 = 0.25;
cout << v1 << v2;
If you know the type stored in an object, you can get it very easily: instead of the risky *reinterpret_cast<X*> you would do: boost::get<X>()
And boost offers a visitation mecanism, to provide in an elegant manner the adequate type dependent code that it has to use for processing a variant objet. You'll find some nice examples in the link at the beginning of this answer.
Consider using Boost.PropertyTree, it implements the "hierarchical" map and also parsers to read configuration from files in some common formats. It stores the values by default in std::string format, but uses boost::lexical_cast to support setting and getting them in other types. If you want, you can use Boost.Any or Boost.Variant to store the values, but that would lose some parsing functionality.
Apologies in advanced if this is the wrong site, please let me know if it is!
I've written a function that checks to see whether a key exists in a particular std::map and wondered if this is a good practise to use, and, whether or not anyone can throw any pointers on improvements.
The std::map allows for multiple data-types to be accepted for the value.
union Variants {
int asInt;
char* asStr;
Variants(int in) { asInt = in; }
Variants() { asInt = 0;}
Variants(char* in) { asStr = in; }
operator int() { return asInt; }
operator char*() { return asStr; }
};
template<typename T, typename Y>
bool in_map(T value, std::map<T, Y> &map)
{
if(map.find(value) == map.end()) {
return false;
}else{
return true;
}
}
And I can then use in main the following:
std::map<string, Variants> attributes;
attributes["value1"] = 101;
attributes["value2"] = "Hello, world";
if(in_map<std::string, Variants>("value1", attributes))
{
std::cout << "Yes, exists!";
}
Any help or advise would be greatly appreciated. Sorry if this doesn't comply to the rules or standards. Thanks!
The biggest problem I see with your function is that you're throwing away the resulting iterator.
When you're checking if a key exists in a map, most of the time you want to retrieve/use the associated value after that. Using your function in that case forces you to do a double lookup, at the cost of performance. I would just avoid the use of the function altogether, and write the tests directly, keeping the iterator around for later use in order to avoid useless lookups:
auto it = map_object.find("key");
if (it != map_object.end())
use(it->second);
else
std::cout << "not found" << std::endl;
Of course if you're just checking whether a key exists and don't care for the associated value then your function is fine (taking into account what others told you in the comments) but I think its use cases are quite limited and not really worth the extra function. You could just do:
if (map_object.find("key") != map_object.end())
std::cout << "found, but I don't care about the value" << std::endl;
ny pointers on improvements.
sure.
template<typename T, typename Y>
bool in_map(T value, const std::map<T, Y> &map)
{
return map.find(value) != map.end();
}
And I'd place map as 1st parameter (just a preference). Also, because the whole thing fits into single line, you might not even need this function.
You're also throwing away returned iterator, but since you aren't using it, that's not a problem.
Apart from this, does this look ok in terms of coding practise? I.e. Using Union or are there other types I can use such as struct?
Well, using char* doesn't looke like a good idea, because char* implies that you can modify data. char* also implies that this pointer is dynamically allocated and you might want to delete[] that pointer later. And you can't use destructors in unions. If the text cannot be changed, you could use const char*, otherwise you might want to use different datatype. Also see Rule of Three
Next problem - you're trying to place char* and int at the same location. That implies that at some point you're trying to convert pointer to integer. Which is a bad idea, because on 64bit platform pointer might not fit into int, and you'll get only half of it.
Also, if you're trying to store multiple different values in the same variable, you are not indicating which type is being stored anywhere. To do that you would need to enclose union into struct and add field (into struct) that indicates type of stored object. In this case, however, you'll end up reinventing the wheel. So if you're trying to store "universal" type, you might want to look at Boost.Any, Boost.Variant or QVariant. All of those require BIG external libraries, though (either boost or Qt).
Typing
if(in_map<std::string, Variants>("value1", attributes))
seems a bit excessive to me, typing all of that typename syntax makes me want to just use the map.find function instead just out of convenience. However, depending on your compiler, sometimes the template parameters can be interpreted automatically, for example, visual studio will allow this:
if(in_map(std::string("value1"), attributes))
In this case, I had to construct an std::string object to replace the char*, but I've completely removed the template definition from the call, the compiler still figures out what T and Y are based on the parameters given.
However, my recommended advice would be to use #define to define your "function". While it is not really a function, since #define actually just replaces snippets of code directly into the source, it can make things much easier and visually appealing:
#define in_map(value,map) (map.find(value) != map.end())
Then your code to use it would just look like this:
if(in_map("value1", attributes))
You both get the optimization of not using a function call, and the visual appearance like it does in PHP.
I want to create a container (preferably map) that holds values of discrete type:
KEY Value
Omega 1.9
Output myoutput.out
sizex 82
##### ###
where the key is = "std::string" and the value is either of "INT/ DOUBLE/ String"
I tried declaring something like.
template<typename T>
map<string, typename T> mymap;
But sure it doesn't works.
:(
I know that there is simple way, splitting them into different variables but that just results in code bloat. Also I am clear about the fact,
std::map<key_value key, class Allocator = allocator<pair<const Key,T>>
needs to know information about "key" and "value" to generate space during compilation.
But this problem is bugging me for quite a while and just need to sort it :D
Can someone walk me through this :D
#include <map>
using namespace std;
union mytypes_t {
int c;
double i;
char* c;
}
int main()
{
Map<int, mytypes_t> myObject;
}
More on unions
The simple solution, as you mentioned is separating the data into three different arrays and writing a wrapper that will find the element in the appropriate container (assuming that the code that performs the lookup does know the type of the variable, else even this becomes complicated).
Alternatively you can use a variant type (boost variant) or type erasure (boost any) to use a container that will handle the different types. If you cannot use boost, implementing some simple type erasure is not that complicated, but I would stay away from it unless you really need it (i.e. prefer a pre canned over-the-shelf solution to your own square wheel)
I have an array of constant data like following:
enum Language {GERMAN=LANG_DE, ENGLISH=LANG_EN, ...};
struct LanguageName {
ELanguage language;
const char *name;
};
const Language[] languages = {
GERMAN, "German",
ENGLISH, "English",
.
.
.
};
When I have a function which accesses the array and find the entry based on the Language enum parameter. Should I write a loop to find the specific entry in the array or are there better ways to do this.
I know I could add the LanguageName-objects to an std::map but wouldn't this be overkill for such a simple problem? I do not have an object to store the std::map so the map would be constructed for every call of the function.
What way would you recommend?
Is it better to encapsulate this compile time constant array in a class which handles the lookup?
If the enum values are contiguous starting from 0, use an array with the enum as index.
If not, this is what I usually do:
const char* find_language(Language lang)
{
typedef std::map<Language,const char*> lang_map_type;
typedef lang_map_type::value_type lang_map_entry_type;
static const lang_map_entry_type lang_map_entries[] = { /*...*/ }
static const lang_map_type lang_map( lang_map_entries
, lang_map_entries + sizeof(lang_map_entries)
/ sizeof(lang_map_entries[0]) );
lang_map_type::const_iterator it = lang_map.find(lang);
if( it == lang_map.end() ) return NULL;
return it->second;
}
If you consider a map for constants, always also consider using a vector.
Function-local statics are a nice way to get rid of a good part of the dependency problems of globals, but are dangerous in a multi-threaded environment. If you're worried about that, you might rather want to use globals:
typedef std::map<Language,const char*> lang_map_type;
typedef lang_map_type::value_type lang_map_entry_type;
const lang_map_entry_type lang_map_entries[] = { /*...*/ }
const lang_map_type lang_map( lang_map_entries
, lang_map_entries + sizeof(lang_map_entries)
/ sizeof(lang_map_entries[0]) );
const char* find_language(Language lang)
{
lang_map_type::const_iterator it = lang_map.find(lang);
if( it == lang_map.end() ) return NULL;
return it->second;
}
There are three basic approaches that I'd choose from. One is the switch statement, and it is a very good option under certain conditions. Remember - the compiler is probably going to compile that into an efficient table-lookup for you, though it will be looking up pointers to the case code blocks rather than data values.
Options two and three involve static arrays of the type you are using. Option two is a simple linear search - which you are (I think) already doing - very appropriate if the number of items is small.
Option three is a binary search. Static arrays can be used with standard library algorithms - just use the first and first+count pointers in the same way that you'd use begin and end iterators. You will need to ensure the data is sorted (using std::sort or std::stable_sort), and use std::lower_bound to do the binary search.
The complication in this case is that you'll need a comparison function object which acts like operator< with a stored or referenced value, but which only looks at the key field of your struct. The following is a rough template...
class cMyComparison
{
private:
const fieldtype& m_Value; // Note - only storing a reference
public:
cMyComparison (const fieldtype& p_Value) : m_Value (p_Value) {}
bool operator() (const structtype& p_Struct) const
{
return (p_Struct.field < m_Value);
// Warning : I have a habit of getting this comparison backwards,
// and I haven't double-checked this
}
};
This kind of thing should get simpler in the next C++ standard revision, when IIRC we'll get anonymous functions (lambdas) and closures.
If you can't put the sort in your apps initialisation, you might need an already-sorted boolean static variable to ensure you only sort once.
Note - this is for information only - in your case, I think you should either stick with linear search or use a switch statement. The binary search is probably only a good idea when...
There are a lot of data items to search
Searches are done very frequently (many times per second)
The key enumerate values are sparse (lots of big gaps) - otherwise, switch is better.
If the coding effort were trivial, it wouldn't be a big deal, but C++ currently makes this a bit harder than it should be.
One minor note - it may be a good idea to define an enumerate for the size of your array, and to ensure that your static array declaration uses that enumerate. That way, your compiler should complain if you modify the table (add/remove items) and forget to update the size enum, so your searches should never miss items or go out of bounds.
I think you have two questions here:
What is the best way to store a constant global variable (with possible Multi-Threaded access) ?
How to store your data (which container use) ?
The solution described by sbi is elegant, but you should be aware of 2 potential problems:
In case of Multi-Threaded access, the initialization could be skrewed.
You will potentially attempt to access this variable after its destruction.
Both issues on the lifetime of static objects are being covered in another thread.
Let's begin with the constant global variable storage issue.
The solution proposed by sbi is therefore adequate if you are not concerned by 1. or 2., on any other case I would recommend the use of a Singleton, such as the ones provided by Loki. Read the associated documentation to understand the various policies on lifetime, it is very valuable.
I think that the use of an array + a map seems wasteful and it hurts my eyes to read this. I personally prefer a slightly more elegant (imho) solution.
const char* find_language(Language lang)
{
typedef std::map<Language, const char*> map_type;
typedef lang_map_type::value_type value_type;
// I'll let you work out how 'my_stl_builder' works,
// it makes for an interesting exercise and it's easy enough
// Note that even if this is slightly slower (?), it is only executed ONCE!
static const map_type = my_stl_builder<map_type>()
<< value_type(GERMAN, "German")
<< value_type(ENGLISH, "English")
<< value_type(DUTCH, "Dutch")
....
;
map_type::const_iterator it = lang_map.find(lang);
if( it == lang_map.end() ) return NULL;
return it->second;
}
And now on to the container type issue.
If you are concerned about performance, then you should be aware that for small data collection, a vector of pairs is normally more efficient in look ups than a map. Once again I would turn toward Loki (and its AssocVector), but really I don't think that you should worry about performance.
I tend to choose my container depending on the interface I am likely to need first and here the map interface is really what you want.
Also: why do you use 'const char*' rather than a 'std::string'?
I have seen too many people using a 'const char*' like a std::string (like in forgetting that you have to use strcmp) to be bothered by the alleged loss of memory / performance...
It depends on the purpose of the array. If you plan on showing the values in a list (for a user selection, perhaps) the array would be the most efficient way of storing them. If you plan on frequently looking up values by their enum key, you should look into a more efficient data structure like a map.
There is no need to write a loop. You can use the enum value as index for the array.
I would make an enum with sequential language codes
enum { GERMAN=0, ENGLISH, SWAHILI, ENOUGH };
The put them all into array
const char *langnames[] = {
"German", "English", "Swahili"
};
Then I would check if sizeof(langnames)==sizeof(*langnames)*ENOUGH in debug build.
And pray that I have no duplicates or swapped languages ;-)
If you want fast and simple solution , Can try like this
enum ELanguage {GERMAN=0, ENGLISH=1};
static const string Ger="GERMAN";
static const string Eng="ENGLISH";
bool getLanguage(const ELanguage& aIndex,string & arName)
{
switch(aIndex)
{
case GERMAN:
{
arName=Ger;
return true;
}
case ENGLISH:
{
arName=Eng;
}
default:
{
// Log Error
return false;
}
}
}