How to convert from a string to a double to a double* - c++

I'm learning C++ so this may be a basic question, however, it is a real life problem. I need to convert from a string to a double and then in turn to a double* in the most elegant/modern way possible (>C++98).
The structure is provided by a C based framework (I've simplified the code here as this is the crux of the problem only) and I cannot change the framework as this interfaces with the closed source Metatrader4 trading application (non C based). The programming interface requires a pointer to be passed to the structure.
The strings are being read from a csv file containing a dump which I have taken from the Metatrader4 application. The details of which are beyond this problem. However, the inputs remain strings hence are the origin type.
I appreciate the method used in the framework may be old skool but that's part of life. It doesn't mean that I can't aspire to do something better in my code, hence the reason I asked for elegant/modern solutions. If they don't exist then I'll be forced to use new as someone has already suggested.
I currently have the following none working code:
#include <string>
struct bidAsk
{
double *bid;
double *ask;
};
int main()
{
bidAsk ba;
ba.bid = std::stod("1.100");
ba.ask = &std::stod("1.102");
}
However, both of the above conversion methods fail with conversion errors.
The first line results in an error which states:
E0513 a value of type "double" cannot be assigned to an entity of type "double *"
The second line results in the following error:
E0158 expression must be an lvalue or a function designator
I've also tried static_cast, const_cast, make_unique and (double*) casting with no luck.
Thanks in advance.

The problem is you need some actual values for your pointers to point at. They can't just point at the temporary values returned from your number conversion functions.
struct bidAsk
{
double* bid;
double* ask;
};
int main()
{
bidAsk ba;
// these have to exist somewhere that lives as long as the
// bidAsk object that points to them.
double bid_value = std::stod("1.100");
double ask_value = std::stod("1.102");
ba.bid = &bid_value; // just pointing to the real values above
ba.ask = &ask_value;
}

As others mentioned in the comments, someone has to own the objects, the pointers are pointing at.
extern C {
struct bidAsk
{
double *bid;
double *ask;
};
}
struct BidAskWrapper
{
BidAskWrapper(const std::string& sbid, const std::string& sask)
:bid{std::stod(sbid)}, ask{std::stor(sask)}
{}
//Note: bidAsk valid only till the lifetype of the wrapper
bidAsk make_c_struct() {
return {&bid, &ask};
}
double bid, ask;
};

Related

C++ Type-safe detection of the offset of a structure

I'm playing a bit with the C++ syntax to figure out a generalized way to keep track of an offset within a class, sort of like offsetof, but in a type-safe way and without #defines
I know that a template class can be template-parametrized with fields, besides types and constants. So I came out with this prototype:
#include <iostream>
template <typename class_type, typename field_type>
struct offsetter
{
offsetter(const char* name, field_type class_type::*field)
: name(name)
{
fprintf(stderr, "%zu\n", field);
}
const char* const name;
};
struct some_struct
{
float avg;
int min;
int max;
struct internal
{
unsigned flag;
int x;
} test;
char* name;
};
int main()
{
offsetter<some_struct, float>("%h", &some_struct::avg);
offsetter<some_struct, int>("%h", &some_struct::min);
offsetter<some_struct, char*>("%h", &some_struct::name);
offsetter<some_struct, some_struct::internal>("x", &some_struct::test);
return 0;
}
This code is actually able to print the field offset, but I'm not really sure on what I'm doing here. Indeed it feels utterly wrong to reference field without referring to an instance (foo.*field).
But it does the job: it prints the offset. My guess is that I'm hitting on some loophole though, since for instance I can't assign size_t offset = field.
I figured out I probably want something like this:
size_t offset = (&(std::declval<class_type>().*field) - &(std::declval<class_type>()))
Which however wont' work as I can't take the address of an xvalue:
taking address of xvalue (rvalue reference)
Is there any way to do this?
AFAIK there isn't a standard way of doing this. Even the standard offsetof is defined only for standard layout types.
What you are doing is UB. You are using the wrong specifier zu. There isn't much you can do with a member pointer. You can't even do pointer arithmetics on them, you can't convert to char* nor to an integer type.
Also if your assumption is that a member pointer is just an integer representing the offset from the beginning of the structure that is false, not only in theory, but also in practice. Having multiple inheritance and virtual inheritance made sure of that.

c++ changing implicit conversion from double to int

I have code which has a lot of conversions from double to int . The code can be seen as
double n = 5.78;
int d = n; // double implicitly converted to a int
The implicit conversion from double to int is that of a truncation which means 5.78 will be saved as 5 . However it has been decided to change this behavior with custom rounding off .
One approach to such problem would be to have your own DOUBLE and INT data types and use conversion operators but alas my code is big and I am not allowed to do much changes . Another approach i thought of was to add 0.5 in each of the numbers but alas the code is big and i was changing too much .
What can be a simple approach to change double to int conversion behaviour which impact the whole code.
You can use uniform initialization syntax to forbid narrowing conversions:
double a;
int b{a}; // error
If you don't want that, you can use std::round function (or its sisters std::ceil/std::floor/std::trunc):
int b = std::round(a);
If you want minimal diff changes, here's what you can do. Please note, though, that this is a bad solution (if it can be named that), and much more likely leaving you crashing and burning due to undefined behavior than actually solving real problems.
Define your custom Int type that handles conversions the way you want it to:
class MyInt
{
//...
};
then evilly replace each occurence of int with MyInt with the help of preprocessor black magic:
#define int MyInt
Problems:
if you accidentally change definitions in the standard library - you're in the UB-land
if you change the return type of main - you're in the UB-land
if you change the definition of a function but not it's forward declarations - you're in the UB/linker error land. Or in the silently-calling-different-overload-land.
probably more.
Do something like this:
#include <iostream>
using namespace std;
int myConvert (double rhs)
{
int answer = (int)rhs; //do something fancier here to meet your needs
return answer;
}
int main()
{
double n = 5.78;
int d = myConvert(n);
cout << "d = " << d << endl;
return 0;
}
You can make myConvert as fancy as you want. Otherwise, you could define your own class for int (e.g. myInt class) and overload the = operator to do the right conversion.

Convert void* to a dynamic type

I have a double variable i, that is converted to a void pointer named pointer:
double i = 3;
void *pointer = &i;
When I like to convert the void pointer back to double I used:
double p = *((double*) pointer);
I would like to convert the void pointer to the type I will send as a char*:
char* myType= typeid(i).name();//get the name of type of "i"
int p = *((myType*) pointer); // how to implement?
Is it possible?
instead of
char* myType= typeid(i).name();//get the name of type of "i"
int p = *((myType*) pointer); // how to implement?
use
typedef decltype(i) myType;
myType p = *((myType*) pointer);
or better:
typedef decltype(i) myType;
auto p = *reinterpret_cast<myType*>(pointer);
Works with c++11 or later. If you want to decltype on older c++ compilers, it is emulated in boost.
Edit. This is probably different from what you wanted to do, which I suppose is something like this:
void myFunction(void* unknownParam) {
typedef (realTypeOf unknownParam) RealType; // <-- this is not real c++
RealType &a = *reinterpret_cast<RealType*>(unknownParam)
//do stuff using 'a'
}
This is not possible in C++, but there is a reason: it doesn't make much sense.
And the reason is that for myFunction to be valid the //do stuff using 'a' part should be valid for whatever type RealType ends up being. As such, it cannot rely on any feature the RealType type have: it cannot use any of its methods, it cannot use any operator, it cannot even know whether it is a class or not. Basically, you cannot do anything more with it than what you would already be able to do on a void*, so giving the type a name doesn't really help you much.
A language feature that is similar to what you want (but not quite it) is type reflection, which is not present in C++, but you can find it in language such as Java, Objective-C or C#. Basically, you ask the object itself if it has a certain method, and eventually call it. An example in Objective-C
-(void)myFunction:(id)unknownParam {
if([unknownParam respondsToSelector:#selector(myMethod)])
[unknownParam performSelector:#selector(myMethod)]
}
C/C++ does not work well to interchange datatype like for example JavaScript variables
Format of int value will be different than double value format (floating point) in binary
You cannot get original data type using typeid after it has been casted to void*. Also note that typeid will have different output on different OS and compilers
double dValue = 77.7;
void* pValue = &dValue;
//output "pV" / pointer void (depending on compiler and OS)
std::cout << typeid(dValue).name() << std::endl;
To cast from void* using string you can make rules like following. Or you can try to use C++ template functions in specific cases.
int iOutValue = 0;
double dOutValue = 0;
char* name = "double";
if(!strcmp(name, "int"))
{
iOutValue = *((int*)pValue);
}
else if(!strcmp(name, "double"))
{
dOutValue = *((double*)pValue);
}
If instead of passing around void* you used some kind of variant type, you would be able to convert it back.
If you use a string to indicate the type you will need some kind of map from string to actual type. Although you can go from type to string, there is no conversion back.
Assuming you know your underlying data is always numeric in some way, there are ways to have special discrete variants that only contain numbers. The simplest would be to store a union of a 64-bit int and a double, and some flag indicating which one you have, and then a method to convert to any numeric type, asDouble(), asLong() etc.

Returning an array ... rather a reference or pointer to an array

I am a bit confused. There are two ways to return an array from a method. The first suggests the following:
typedef int arrT[10];
arrT *func(int i);
However, how do I capture the return which is an int (*)[]?
Another way is through a reference or pointer:
int (*func(int i)[10];
or
int (&func(int i)[10];
The return types are either int (*)[] or int (&)[].
The trouble I am having is how I can assign a variable to accept the point and I continue to get errors such as:
can't convert int* to int (*)[]
Any idea what I am doing wrong or what is lacking in my knowledge?
If you want to return an array by value, put it in a structure.
The Standard committee already did that, and thus you can use std::array<int,10>.
std::array<int,10> func(int i);
std::array<int,10> x = func(77);
This makes it very straightforward to return by reference also:
std::array<int,10>& func2(int i);
std::array<int,10>& y = func2(5);
First, the information you give is incorrect.
You write,
“There are two ways to return an array from a method”
and then you give as examples of the ways
typedef int arrT[10];
arrT *func(int i);
and
int (*func(int i))[10];
(I’ve added the missing right parenthesis), where you say that this latter way, in contrast to the first, is an example of
“through a reference or pointer”
Well, these two declarations mean exactly the same, to wit:
typedef int A[10];
A* fp1( int i ) { return 0; }
int (*fp2( int i ))[10] { return 0; }
int main()
{
int (*p1)[10] = fp1( 100 );
int (*p2)[10] = fp2( 200 );
}
In both cases a pointer to the array is returned, and this pointer is typed as "pointer to array". Dereferencing that pointer yields the array itself, which decays to a pointer to itself again, but now typed as "pointer to item". It’s a pointer to the first item of the array. At the machine code level these two pointers are, in practice, exactly the same. Coming from a Pascal background that confused me for a long time, but the upshot is, since it’s generally impractical to carry the array size along in the type (which precludes dealing with arrays of different runtime sizes), most array handling code deals with the pointer-to-first-item instead of the pointer-to-the-whole-array.
I.e., normally such a low level C language like function would be declared as just
int* func()
return a pointer to the first item of an array of size established at run time.
Now, if you want to return an array by value then you have two choices:
Returning a fixed size array by value: put it in a struct.
The standard already provides a templated class that does this, std::array.
Returning a variable size array by value: use a class that deals with copying.
The standard already provides a templated class that does this, std::vector.
For example,
#include <vector>
using namespace std;
vector<int> foo() { return vector<int>( 10 ); }
int main()
{
vector<int> const v = foo();
// ...
}
This is the most general. Using std::array is more of an optimization for special cases. As a beginner, keep in mind Donald Knuth’s advice: “Premature optimization is the root of all evil.” I.e., just use std::vector unless there is a really really good reason to use std::array.
using arrT10 = int[10]; // Or you can use typedef if you want
arrT10 * func(int i)
{
arrT10 a10;
return &a10;
// int a[10];
// return a; // ERROR: can't convert int* to int (*)[]
}
This will give you a warning because func returns an address of a local variable so we should NEVER code like this but I'm sure this code can help you.

passing variable to function with & in the header

I am doing a procedure and it's working but I'm not sure if it'll work in all cases as it's not conventional.
void func (int &num){
num=blah;
}
int main() {
int num;
func(num);
}
I know the conventional way of doing this is as below but still I have a lot of code in the previous format I prefer not to change as it works just fine. What I don't understand is whether I'm just being lucky.
void func (int* num){
*num=blah;
}
int main() {
int num;
func(&num);
}
In fact there is a bit more complicated version of it as well:
void func(float* &list){
list=new float[3];
}
int main() {
float *list;
func(list);
}
which again I understand the conventional way of doing it is as below.
void func(float** list){
*list=new float[3];
}
int main(){
float *list;
func(&list);
}
Your help is much appreciated as I'm in total confusion.
Your first example is correct - you're passing an int by reference to func().
Your second example also fine (now that you've edited it). In this case, you're passing an int * by value to func().
Your third and fourth examples are also both correct. In the third, you're passing a float * by reference. In the second case, you're passing a float ** by value (which is semantically similar to passing a float * by reference, which might be why you're confusing them).
There's nothing "conventional" or "unconventional" about any of your example code. All of it is 100% correct and will work fine. Though there are some subtle semantic differences between passing pointers by value and passing by references, these examples are ok.
The syntax with int & is not C, but C++. It is a so-called reference. If your C (not C++) compiler accepts is, then it is a non-standard extension (for a C++ compiler it's part of the language, of course).
The basic mechanics of a reference is that it acts as a name (or another name) for an existing object. For example:
int a;
int& b = a;
b = 3; /* equivalent to a = 3 */
One way to think about the reference is as an automatically dereferenced pointer (that's also how it is commonly implemented). That is, the above code is equivalent to
int a;
int* pb = &a;
*pb = 3;
The Form Func(int &x) is the c++ form of pass by reference c does not support this. It is logically equivocation of passing by a pointer. The comnplier take the address for you implicitly in the call.
In C you would allways declare
Func(int *x)
{ ... }
And call it
Func(&SomeInt);