Create unordered_map for CString as key [duplicate] - c++

This question already has answers here:
How do I implement a CString hash function for use with std::unordered_map?
(3 answers)
Closed 5 years ago.
I'm trying to create following unordered_map:
std::unordered_map<CString, CString, std::function<size_t(const CString &data)>> usetResponse(100, [](const CString &data)
{
return std::hash<std::string>()((LPCSTR)data);
});
I provided hash function for CString, but compiler still returns errors:
error C2338: The C++ Standard doesn't provide a hash for this type.
error C2664: 'std::unordered_map<CString,CString,std::hash<_Kty>,std::equal_to<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>>::unordered_map(std::initializer_list<std::pair<const _Kty,_Ty>>,unsigned int,const std::hash<_Kty> &,const _Keyeq &,const std::allocator<std::pair<const _Kty,_Ty>> &)' : cannot convert argument 1 from 'std::unordered_map<CString,CString,std::function<size_t (const CString &)>,std::equal_to<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>>' to 'const std::unordered_map<CString,CString,std::hash<_Kty>,std::equal_to<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>> &'
Please tell me what I'm doing wrong ?

Something like this:
struct CStringHash
{
size_t operator () (const CString &s) const
{
return hash<string>()(static_cast<LPCSTR>(s));
}
};
Then declare the map like this:
unordered_map<CString, CString, CStringHash> map;

Related

A const member function can not deduce parameter type

Here is the code:
vector<ClientInfo*> OpenRABiz::GetHumans() const {
vector<ClientInfo*> vec;
for (auto &c : clients) {
if (!c.isbot) {
vec.push_back(&c);
}
}
return vec; // RVO - return value optimization
}
In visual c++ 2019, compiler indate it:
error C2664: 'void std::vector<ClientInfo *,std::allocator<ClientInfo *>>::push_back(_Ty &&)': cannot convert argument 1 from 'const ClientInfo *' to 'const _Ty &'
The error message: "
const _Ty&" means the c++ template can't deduce the right parameters
.
When I take the const keyword, it compiles successfully.
vector<ClientInfo*> OpenRABiz::GetHumans()
Why?
Your clients is likely a vector of ClientInfo, so in a const-qualified member-functions, the type of client (in the loop) is const ClientInfo&. When you take the address &client, you get a const ClientInfo*, which cannot be converted to a ClientInfo*.
When you remove the const-qualifier, everything works fine because client is then ClientInfo&.
To fix the issue, change the return-type of the function and declaration of vec to std::vector<const ClientInfo*>.

Cannot convert from 'initializer-list' to 'std::initializer_list<Keyword> &'

I'm trying to use an initialization-list to pass a list of keywords to a tokenizer to register. But it does not work in Visual Studio 2013. It works in gcc at ideone.com. Is there any way to use this or a similar syntax in VS?
struct Keyword
{
const char* name;
int id;
};
void AddKeywords(int group, std::initializer_list<Keyword>& lis) {}
// usage
AddKeywords(ITEM_TYPE, {
{ "weapon", IT_WEAPON },
{ "armor", IT_ARMOR }
});
Full error:
item.cpp(810): error C2664: 'void AddKeywords(int,std::initializer_list<Keyword> &)' : cannot convert argument 2 from 'initializer-list' to 'std::initializer_list<Keyword> &'
You are trying to bind a temporary to a non-const reference;
std::initializer_list<Keyword>& lis
Try either;
std::initializer_list<Keyword> const& lis
Or
std::initializer_list<Keyword> lis
When building with GCC, enable -Wall -pedantic it should give you an error then as well.

use external function as member-function pointer

Is it possible in C++ to create a function which is not defined in class A but can be treated like a method pointer? Eg.:
typedef bool (A::*MethodType)(int a);
MethodType g_someMethod = &A::SomeMethod;
Now, I want to create a new function AnotherMethod which is of the type MethodType. I have tried to do the following:
bool A_AnotherMethod(A* _this, int a) {
std::cout << __FUNCTION__ << "\n";
return true;
}
MethodType g_someMethod = A_AnotherMethod;
// ...
(this->*g_someMethod )(42);
But I get
error C2440: '=' : cannot convert from 'bool (__cdecl *)(A *,int)' to 'bool (__cdecl A::* )(int)'
How to do it correctly?
No, you can't. C++ does not have a feature similar to extension methods in C#.
p.s. Method pointers have clumsy syntax in C++ and are rarely used. But this is the way how they are defined in the language.

C++ list remove_if compile error

The error message I'm getting for the code below is:
error C2662: 'DamageNumbers::IsAlive' : cannot convert 'this' pointer from 'const DamageNumbers' to 'DamageNumbers &'
1> Conversion loses qualifiers
.
bool CheckDamageNumbersAlive(const DamageNumbers& e)
{
return !e.IsAlive();
}
I want to remove objects from a list when IsAlive() returns false for the objects in that list.
Your method
bool DamageNumbers::IsAlive() {...}
should be const:
bool DamageNumbers::IsAlive() const {...}

How to use std::wstring with std::istringstream?

I am trying to write a template function which will extract the value of the given datatype from the given string. I came up with something like this:
template<class T>
static T getValue(const CString& val_in)
{
std::wstring value = val_in;
std::istringstream iss;
iss.str(value);
T val = T();
iss>>val;
return val;
}
But this gives the following error for the iss.str(value) statement.
error C2664: 'void
std::basic_istringstream<_Elem,_Traits,_Alloc>::str(const
std::basic_string<_Elem,_Traits,_Ax>
&)' : cannot convert parameter 1 from
'std::wstring' to 'const
std::basic_string<_Elem,_Traits,_Ax>
&'
So basically, std::istringstream is accepting only std::string . I thought there may be a std::wistringstream but there doesn't seem to be one available. Any clues how can I do it?
My compiler has wistringstream -- this is all it is:
typedef basic_istringstream<wchar_t> wistringstream;