I am trying to write some code to calculate dividend yields. I need to calculate the dividend yield (dividend/stock_price) daily. Dividends are constant. Eventually, I will have to tie the stock price to a dynamic feed, but in the meantime the stock prices may be in their own map. I inserted the dividend amounts for each stock in the class constructor because it is less computationally cumbersome than using conditional statements in the members (i.e if stock = Apple, then dividend is X). I am getting the following error message starting at the '[' before the "AAPL":
**error C2679: binary '[' : no operator found which takes a right-hand operand of type 'const
char [5]' (or there is no acceptable conversion) c:\boost/unordered/unordered_map.hpp(415):
could be 'double &boost::unordered_map<K,T>::operator [](const FinModels::Instrument *const &)'
with
[
K=const FinModels::Instrument *,
T=double
]
while trying to match the argument list '(DividendMap, const char [5])'**
Can anyone help me based on my brief code below and description? Is const Symbol* incorrect type for the key?
Also, if it's bad convention to post the fixed map values in the constructor, please let me know what is better.
Header File
public:
typedef boost::unordered_map<const Symbol*, double> Dividend_Map;
typedef Dividend_Map::iterator Dividend_MapIterator;
private:
Dividend_Map p_dividend_map;
.CPP File
p_dividend_map["AAPL"] = 0.01;
p_dividend_map["BAC"] = 0.01;
p_dividend_map["C"] = 0.01;
The key type for your map is a Symbol *, and you're trying to stick a bunch of const char * into the map. This will not work unless Symbol is typedef'd as char.
Create a Symbol object out of each symbol you want to store in the map and then add the address of that to the map.
Symbol appl("AAPL"); // assuming Symbol has a constructor taking a const char *
p_dividend_map[&appl] = 0.01;
In the example above, the lifetime of aapl must match its lifetime as a member of the map. If the lifetime of aapl expires you'll have the map pointing to an invalid memory location.
You may want to change the map to
typedef boost::unordered_map<Symbol, double> Dividend_Map;
Then use it as
Symbol appl("AAPL");
p_dividend_map[appl] = 0.01;
Related
I'm currently working on a DLL that needs to convert back and forth between the friendly name for a value and the value itself. As this code is used in many places throughout the codebase, I want to try and keep it simple and in a single function or object so I only have to declare them once.
From my reading it looks like CMap is the tool for the job, but I can't seem to discover any combination of template arguments that compiles without errors.
My values are CString and int. I tried the following definition:
CMap<int, int, CString, CString> encodermap;
which compiles, but when I try to add a value:
encodermap["Encoder 1"] = 0;
I get the following compiler errors:
error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2501: 'encodermap' : missing storage-class or type specifiers
error C2040: 'encodermap' : 'int []' differs in levels of indirection from 'CMap<KEY,ARG_KEY,VALUE,ARG_VALUE>'
I've tried changing the CMap to this:
CMap<CString, CString, int, int> encodermap;
but I get the same four errors.
I'm sure I must be missing something but I'm at a loss as to what.
Because of the SDK being used for this work I'm require VS2003
The problem
I think you've inverted the key type and the valye type.
Your original declaration defines int as being the key to be searched for with operator[]. So encodermap[0] = "Encoder 1"; would work.
But when your compiler sees encodermap["Encoder 1"] = 0;, he tries to find an operator[] which takes char* (or something to which char * can be converted to) and returns an int. The last error message tells you that he couldn't find such an operator for your map.
With MSVC 2015, the error message is more concise: C2679.
The solution
You should define your CMap with a CString key and an int value. The trick to know, is that for a CString KEY, the the ARG_KEY should be LPCWSTR . So the right definition would be:
CMap<CString, LPCWSTR, int, int> encodermap;
This permits to use CString as key in the map's operator[].
Now if you use MFC on windows, you probably use UNICODE and wide chars (therefore the LPCWSTR instead of LPCSTR). When calling the operator you then have either to use a CString or a wide literal:
encodermap[L"Encoder 1"] = 0;
encodermap[CString("Encoder 2")] = 1;
Try this:
CMap<CString, LPCTSTR, int, int> encodermap;
This CodeProject article CMap How-to may be of some help.
Many people get confused about CMap's declaration CMap < KEY, ARG_KEY,
VALUE, ARG_VALUE >, why not just CMap < KEY, VALUE >?
In fact, the ultimate data container in CMap is CPair, and the
internal of CPair is {KEY, VALUE}. Therefore, CMap will really store a
KEY, and not ARG_KEY. However, if you check with the MFC source code,
almost all the internal parameters passing within CMap itself is
called with ARG_KEY and ARG_VALUE, therefore, using KEY & as ARG_KEY
seems always a correct thing, except when:
You are using primitive date types like int, char, where pass-by-value makes no difference (may be even faster) with
pass-by-reference.
If you use CString as KEY, you should use LPCTSTR as ARG_KEY and not CString &, we will talk more about this later.
Edit: Cristophe, another option for the assignment is encodermap[_T("Encoder 1")] = 0;, which will work for single-byte, multi-byte or Unicode with the LPCTSTR typedef. You will also need to #include <tchar.h>.
OK, I'm trying to work on a monolith of a program, and I've got a decent amount of the errors sorted through. The one's that's mystifying me right now is when I got "invalid conversion from 'char' to 'const char'" for this line:
sequenceMutation.insert( initialPosition, 'T' );
initialPosition itself is meant to be equal to sequenceIleChains[0] + 3, which corresponds to the index of the last character for the first Isoleucine group (plus one to account for the behavior of insert). I don't know why it would be outputting this, considering I initialize and declare string sequenceMutation locally in the function without const, so if anyone can figure this out, it would be useful.
Additionally, if it may help, I used
string sequenceMutation = sequenceOld[sequence];
to initialize and declare sequenceMutation, where sequenceOld is a vector that I pass by reference using vector<string>& sequenceOld and sequence is a integer value I initialize, declare, pass from the for loop in int main() that I'm putting this function within.
Replace the ' by ", you are inserting a string, not a char, see http://www.cplusplus.com/reference/string/string/insert/
char Substitution::encodeChar(char a, std::map<char, char>&){
return &[a];
}
This is my implementation attempt (based on a pre defined Class header which I may not change for the assignment). In Visual Studio I get the error (see title) over the semicolon?
Trying
&.find(a)
instead gives me "expected an expression" over the period.
I think I spotted somewhere saying something about const char vs. char for this problem, but I can't wrap my head around it. I've used map char char earlier this way, but somehow using it in this context doesn't work.
It looks like you're trying to treat & as a variable name. It's not. Variable names consist only of letters, digits, and underscores.
Actually, in the function parameters, std::map<char, char>& means that the type of the parameter is a "reference to std::map<char, char>". Note that I said "reference to". That's what the & means. It's part of the type and makes the parameter a reference parameter.
So you need to give your parameter a name and then use that name:
char Substitution::encodeChar(char a, std::map<char, char>& my_map){
return my_map[a];
}
We can read the parameter std::map<char, char>& my_map as saying the my_map is a "reference to std::map<char, char>". Then, my_map[a] accessing the key a in that map.
I am using the ldap_modify function to change an attribute value using C++ ...
msgid=ldap_modify_ext_s( ld, dnNameval, ldapmod,NULL,NULL );
The problem is the mod_val argument in that function ...
LDAP *id;
dnNameval ="distinguised name";
In the ldapmod there are three values ...
mod_type="attribute to be changed";
mod_op=LDAP_MOD_REPLACE;
ldapmod struct
The ldapmod struct is:
typedef struct ldapmod {
int mod_op;
char *mod_type;
union {
char **modv_strvals;
struct berval **modv_bvals;
} mod_vals;
#define mod_values mod_vals.modv_strvals
#define mod_bvalues mod_vals.modv_bvals
} LDAPMod;
I tried passing the value like this:
mod_vals=(PWCHAR*){"bala",Null};
which resulted in the error
error C2679: binary '=' : no operator found which takes a right-hand operand
of type 'PWCHAR *' (or there is no acceptable conversion)
I also tried this:
mod_vals.modv_strvals=(PWCHAR*) Password1;
mod_vals.modv_bvals=NULL;
but then the array has a null value...
Can anyone help me work out how to pass the values in that variable? Do I need to include any additional header files? I am already using the winldap.h header.
Thanks in advance.
This won't work:
mod_vals = (PWCHAR*){"bala",Null};
You can't assign a value to a union that way. You have to specify which of the members of the union you want to write to. Also, (PWCHAR *) is the wrong type; you're not dealing with wide characters. Even if you were, you can't convert a string just by casting it.
This won't work either:
mod_vals.modv_strvals=(PWCHAR*) Password1;
mod_vals.modv_bvals=NULL;
The modv_strvals member is a pointer-to-pointer, not just a pointer, and it doesn't make sense to write to two members of a union; they're mutually exclusive. Depending on context you either use modv_strvals or modv_bvals, never both.
You probably want to do this:
mod_vals.modv_strvals = {"bala", Null};
In c++ can we cast an object to an integer ?
Clarifying my question - Suppose I have created an interface to handle file management task like create file, open file, read, write and I want to have one unique handle for every instance of a file. To achieve this can I create a file handle for each instance of the file interface by just type casting that instance to integer ?
To all - I hope now i am clear.
Not all objects. Every object in C++ has a type. That type of an object defines whether a cast to int exists, and if so, what algorithm is used.
If you have an object and want to cast it to int then you need to explicitly provide operator int for that class.
class File
{
public:
...
...
operator int() { return int(this); }
...
}
Then
File myFile;
int myFileHandle = myFile;
I would rather convert to a long type. This is safer when a pointer value is converted to an integral type on an x64 machine. You can just use reinterpret_cast<long>(myInterfacePointer) in that case.
you can, but it depend on the sizeof(YourObject) compared to sizeof(int), by casting any object to int you will access the first 4 bytes part of your object (assuming sizeof(int) == 4), if your object is smaller than sizeof(int) somewhere you will get access violation or crash. to cast :
`
MyObject object;
int castedObject = *((int*)&object);
`
to cast without pointer intermediate, you must provide typecast operator inside MyObject class. or you can declare global static function of int& operator=(const MyObject& object){...}
Edit: Since you are mapping files to a unique handle, you can use a std::vector<std::string> or a vector<shared_ptr<fstream> > or a vector<FILE*>.
On a POSIX-compliant system there is also fileno to convert a FILE* into its file descriptor which is an int.
To get the hash: Use the hash_value function from boost.
To convert any value to integer lexically: Use the lexical_cast<int> function from boost
To cast the value to integer: Just use (int)value.
For the above to work, the class you're going to convert needs to implement some special member functions e.g. operator<< and operator int.
To convert an object into an arbitrary unique integer, use (int)&value.
To get a random integer, use rand().
Why not just get the file descriptor/handle/whatever ID from the operating system and use that? Most systems have some kind of concept like that.
Consider using void * instead of int for the handles if you really want them to be pointers. Then casting a pointer-to-object to a handle is easy, and you can still hide the implementation away.
In response to #potatoswatter's comment to my first response.
I don't like the idea of casting objects. I would rather use a hashing function that produces an integer hash, say based on the filename or read/write flags. Now, I have to post another answer
class File
{
public:
...
...
operator int();
...
private:
char fileName[];
int flags;
};
The integer conversion operator is now a hashing function:
File::operator int()
{
int hash = 0;
int c;
char *str = fileName;
while (c = *str++)
hash += c;
hash += flags;
return hash;
}
I know the hash function is lousy. But you can avoid casts that are lousier and come up with your own hashing function that suits your needs better.