How to put const string value in map - c++

I want to create a map ,
std::map <MESSAGE_CATEGORY, const std::string> m_mapResponseDesc;
I am using operator[] to append a value in the map:
m_mapResponseDesc[STATUS_LIMIT] = "Limit has been exceeded";
STATUS_LIMIT is of type enum.
I am getting error:
error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)
Please point out what mistake I have done. I am not getting any clue.

Since operator[] returns a reference (to a const std::string) you will need to use the insert() method instead.
#include <map>
#include <string>
using namespace std;
int main()
{
std::map<int, const std::string> m;
m.insert(std::make_pair(1, "Hello"));
return 0;
}
Update for C++11:
You can do this even easier now:
std::map<int, const std::string> status = {
{200, "OK"},
{404, "Not Found"}
};

Related

Creating an array of string_view elements throws error: unable to find string literal operator ‘operator""sv’ with

I have the following (modified) code where I want to create an array of string_view type objects.
I see this error when compiling corresponding to each line
unable to find string literal operator ‘operator""sv’ with ‘const char [8]’, ‘long unsigned int’ arguments
"Sensor2"sv,
The code:
#include <iostream>
#include <array>
#include <string_view>
struct Abc
{
static constexpr std::array<std::string_view, 6> SomeValues = {
"Sensor1"sv,
"Sensor2"sv,
"Actuator1"sv,
"Actuator2"sv,
"Cpu1"sv,
"Cpu2"sv
};
};
int main()
{
Abc abc;
std::cout<<abc.SomeValues[3];
return 0;
}
You need using namespace std::literals;.
See also this question.

How to iterate through a range-based for loop when the data type of the array is const char *?

I am trying to solve the following question:
https://www.codewars.com/kata/54bf1c2cd5b56cc47f0007a1/train/cpp in C++.
When I try to iterate over a range based for loop I get the following error ->
In file included from main.cpp:6:
./solution.cpp:14:13: error: invalid range expression of type 'const char *'; no viable 'begin' function available
for(auto x: in){
^ ~~
1 error generated.
The code ->
Also , further on I am also encountering an error while comparing, if(x!=' ') that I am comparing wrong data types, I am trying to understand the dereferencing concept and its escaping my understanding. can someone break down the explanation for me please?
#include <unordered_map>
#include <string.h>
using namespace std;
size_t duplicateCount(const std::string& in); // helper for tests
size_t duplicateCount(const char* in)
{
unordered_map<char , int> hash;
for(auto x: in){
cout<<"char:"<<x<<endl;
if(hash[x]>=0){
hash[x]+=1;
} else {
if(x!=" "){
hash[x]=0;
}
}
}
int ct=0;
for(auto x:hash){
if(x.second>1){
ct++;
}
}
return ct;
}
You just can't use range based for loops with plain old arrays. In your case you could use std::string_view as a wrapper around your char array:
const char* in = "hallo welt";
std::string_view sv(in);
for(const auto& x: sv){
std::cout<<"char:"<<x<<std::endl;
if(x == 'h')
std::cout<<"h-detected"<<std::endl;
}

std::map with lambda comparator

My below code is giving me compiler error and I an not understanding what wrong I am doing. Can anyone help please?
Basically all I am trying to do is pass a STL map container by reference to a function which would fill it up. This map container also has a comparator lambda associated with it.
#include "stdafx.h"
#include <functional>
#include <map>
using namespace std;
typedef struct _tagAddressBook
{
string strFirstName;
string strLastName;
long nZipCode;
} AddressBook;
void foo(map<string, AddressBook, function<bool(const string&, const string&)>> &myAddressBook)
{
AddressBook addressBookInstance;
addressBookInstance.strFirstName = "Bob";
addressBookInstance.strLastName = "Parker";
addressBookInstance.nZipCode = 12345;
myAddressBook.insert(std::pair<string, AddressBook>(addressBookInstance.strFirstName, addressBookInstance));
}
int _tmain(int argc, _TCHAR* argv[])
{
auto myComparator = [] (const string &strLeft, const string &strRight) { return(strLeft.compare(strRight) <= 0 ? true : false); };
map<string, AddressBook, decltype(myComparator)> myAddressBook(myComparator);
foo(myAddressBook);
return 0;
}
I get the below compilation error on VS2012
Error 1 error C2664: 'foo' : cannot convert parameter 1 from 'std::map<_Kty,_Ty,_Pr>' to 'std::map<_Kty,_Ty,_Pr> &' d:\my projects\mapwithlambdacomparator\mapwithlambdacomparator\mapwithlambdacomparator.cpp 32
2 IntelliSense: a reference of type "std::map<std::string, AddressBook, std::function<bool (const std::string &, const std::string &)>, std::allocator<std::pair<const std::string, AddressBook>>> &" (not const-qualified) cannot be initialized with a value of type "std::map<std::string, AddressBook, lambda []bool (const std::string &strLeft, const std::string &strRight)->bool, std::allocator<std::pair<const std::string, AddressBook>>>" d:\My Projects\MapWithLambdaComparator\MapWithLambdaComparator\MapWithLambdaComparator.cpp 32
Lambda functions are not related to std::function. In fact, each is its own class type. If you want to do what it appears you do, you can do it by template through foo and let deduction sort it out.
template <typename Cmp>
void foo(map<std::string, AddressBook, Cmp> &myAddressBook)
{
AddressBook addressBookInstance;
addressBookInstance.strFirstName = "Bob";
addressBookInstance.strLastName = "Parker";
addressBookInstance.nZipCode = 12345;
myAddressBook.insert(std::pair<string, AddressBook>(addressBookInstance.strFirstName, addressBookInstance));
}
This works on my toolchain, "Apple LLVM version 5.0 (clang-500.2.75) (based on LLVM 3.3svn)". I see no reason it would not work with your toolchain as well.
Please make an alias:
using AdressBookMap = map<string, AddressBook, function<bool(const string&, const string&)>>;
Then use it:
void foo(AddressBookMap& myAddressBook)
{
// ...
}
int main(int argc, char* argv[])
{
auto myComparator = [] (...) { ... };
AddressBookMap myAddressBook(myComparator);
foo(myAddressBook);
return 0;
}
As Whoz said, lambdas are not std::function; the latter can be implicitly constructed from the former, but they don't have the same type. This means a std::map parametrized by one is completely unrelated to a std::map parametrized by the other.

Sorting std::map based on the data (map->vector->sort)

I want to sort a std::map based on the data (second field). However the second field itself is a structure and I want to sort based on one of its elements. Based on what is suggested here and its reference, decided to copy the map to a vector and then use std::sort. Here is the class implementtion
#include <iostream>
#include <vector>
#include <map>
#include <utility>
class foo() {
foo() {}
void bar()
{
aDeltaMap theDeltaMap;
// insert some elements to theDeltaMap
aDeltaVector theDeltaVec( theDeltaMap.begin(), theDeltaMap.end() );
std::sort(theDeltaVec.begin(), theDeltaVec.end(), descend_rep<deltaPair>() ); //ERROR
}
private:
typedef struct entry {
entry( int r, int mc ) : rep(r), missCounter(mc) {}
int rep;
int missCounter;
} aDeltaEntry;
typedef std::map< int, aDeltaEntry > aDeltaMap;
typedef std::pair< int, aDeltaEntry > deltaPair;
typedef std::vector< deltaPair > aDeltaVector;
struct descend_rep
: std::binary_function<deltaPair,deltaPair,bool>
{
inline bool operator()(const deltaPair& lhs, const deltaPair& rhs) { return lhs.second.rep > rhs.second.rep; };
};
};
At the line of sort function, I get this error
error C2275: illegal use of this type as an expression
error C2059: syntax error : ')'
What did I missed?
One error is that descent_rep is not a class template, so you need to replace
descend_rep<deltaPair>()
by
descend_rep()
You should make descend_rep's bool operator() const too, since comparing its operands does not change its state.

C++ error: no viable conversion from 'mapped_type' to 'int'

I am trying to implement the a map from the C++ STL as follows:
#include <string>
#include <iostream>
#include <map>
using namespace std;
#include "assembler.h"
// This Class makes use of the Map Template from the Standart Template Library
// All addresses are stored as numerical (Dec) integers
SymbolTable::SymbolTable() { // Constructor
map <string, int> symbolTable;
int address = 0;
}
void SymbolTable::addEntry(string symbol, int address) {
symbolTable[symbol] = address;
address++;
}
// Returns true if symbolTable already contains symbol
bool SymbolTable::contains(string symbol) {
if (symbolTable.find(symbol) == symbolTable.end()) { return true; }
else { return false; }
}
int SymbolTable::getAddress(string symbol) {
return symbolTable[symbol];
}
I try to compile this with
c++ *.cpp -0 assembler.out
and I get the following error message:
symboltable.cpp:57:9: error: no viable conversion from 'mapped_type' (aka 'std::basic_string<char>') to 'int'
return symbolTable[symbol];
^~~~~~~~~~~~~~~~~~~
1 error generated.
I have searched for this error online and all I get is bug reports relating to the STL and I cannot figure out if those reports are the same problem I am having and if so how to get around it. Am I doing something wrong?
I have tried (probably stupidly) to typecast the offending line as
return (int) symbolTable[symbol];
Thank you for any help.
My header file declares the class as:
class SymbolTable {
public:
SymbolTable();
void addEntry(string, int);
bool contains(string);
int getAddress(string);
private:
map <string, string> symbolTable;
int address;
};
This:
SymbolTable::SymbolTable() { // Constructor
map <string, int> symbolTable;
^
^
is a function-local variable, not a member variable. It is not the same as the symbolTable that you're accessing in e.g. getAddress, which presumably is a member variable. You haven't shown the class body, but my guess is that it's defined differently.