Reputation: 63
I just deleted a question that had set for 4 hours unanswered. I have mostly been able to answer it for myself through some trial and error and seem to have a good handle on it except for one piece. Why cant I declare my map as a const or was I doing it wrong? Complete example is at the bottom.
in class header
const std::map <char, char> UppercaseConvert;
in class constructor
const UppercaseConvert = { { 'A','a' },{ 'B','b' },{ 'C','c' },{ 'D','d' },{ 'E','e' },{ 'F','f' },
{ 'G','g' },{ 'H','h' },{ 'I','i' },{ 'J','j' },{ 'K','k' },{ 'L','l' },
{ 'M','m' },{ 'N','n' },{ 'O','o' },{ 'P','p' },{ 'Q','q' },{ 'R','r' },
{ 'S','s' },{ 'T','t' },{ 'U','u' },{ 'V','v' },{ 'W','w' },{ 'X','x' },
{ 'Y','y' },{ 'Z','z' } };
It will compile and work if I remove the const from both declaration and definition so it's not the end of the world. But, since this should be static shouldn't it have the const type?
This is the function it is used in:
std::string BCLogic::ConvertToLowerCase(FString word) {
std::string ConvertedString;
for (char character : word) {
if (UppercaseConvert[character]) {
ConvertedString.push_back(UppercaseConvert[character]);
}
else ConvertedString.push_back(character);
}
return ConvertedString;
}
Edit: Complete Example that will not compile unless you remove const:
#include <iostream>
#include <string>
#include <map>
class Converter {
public:
Converter();
std::string ConvertToLowerCase(std::string);
const std::map <char, char> UppercaseConvert; //remove const to compile
};
Converter::Converter() {
//remove const to compile
const UppercaseConvert = { { 'A','a' },{ 'B','b' },{ 'C','c' },{ 'D','d'},{ 'E','e' },{ 'F','f' },
{ 'G','g' },{ 'H','h' },{ 'I','i' },{ 'J','j' },{ 'K','k' },{ 'L','l' },
{ 'M','m' },{ 'N','n' },{ 'O','o' },{ 'P','p' },{ 'Q','q' },{ 'R','r' },
{ 'S','s' },{ 'T','t' },{ 'U','u' },{ 'V','v' },{ 'W','w' },{ 'X','x' },
{ 'Y','y' },{ 'Z','z' } };
}
std::string Converter::ConvertToLowerCase(std::string word) {
std::string ConvertedString;
for (char character : word) {
if (UppercaseConvert[character]) {
ConvertedString.push_back(UppercaseConvert[character]);
}
else ConvertedString.push_back(character);
}
return ConvertedString;
}
int main() {
Converter ThisConverter;
std::cout << "Enter a word in Caps:";
std::string word;
std::getline(std::cin, word);
word = ThisConverter.ConvertToLowerCase(word);
std::cout << "\n Your converted word is : " << word << std::endl;
return 0;
}
Upvotes: 1
Views: 1356
Reputation: 141554
const UppercaseConvert =
is a syntax error. When you refer to a variable that already exists, you just use its name, UppercaseConvert
here. You don't repeat some parts of its declaration or qualifiers.
Let's talk about the line :
UppercaseConvert = { { 'A','a' },{ 'B','b' },{ 'C','c' },{ 'D','d'},{ 'E','e' },{ 'F','f' },
{ 'G','g' },{ 'H','h' },{ 'I','i' },{ 'J','j' },{ 'K','k' },{ 'L','l' },
{ 'M','m' },{ 'N','n' },{ 'O','o' },{ 'P','p' },{ 'Q','q' },{ 'R','r' },
{ 'S','s' },{ 'T','t' },{ 'U','u' },{ 'V','v' },{ 'W','w' },{ 'X','x' },
{ 'Y','y' },{ 'Z','z' } };
This is called assignment. You are changing the value that UppercaseConvert
already has, to be a different value.
So, it is not possible to make UppercaseConvert
be const
and also have this line. Because if it is const
then you cannot change its value.
I guess that what you intended to do was to initialize UppercaseConvert
. To initialize means to supply a value which the variable will hold upon its creation. The way you wrote it so far, the variable is initailized to be an empty map and you try to change the map later on to have entries in it. The constructor body runs after the member variables have finished being initialized.
Link to further reading about initialization for non-static members
In comments it seems you also want the map to be static. Probably a good idea. For a static
member, you do not put anything in the constructor. This is because the constructor is used to construct instances of your class. But a static member is not associated with any particular instance. A static member means that there is one instance of that member in total.
The class definition should contain:
static const std::map<char, char> UppercaseConvert;
and then in the .cpp
file where you implement this class, but outside of any function, you write the definition with initializer (and you do not repeat the word static
here):
const std::map<char, char> BCLogic::UppercaseConvert =
{ { 'A','a' },{ 'B','b' },{ 'C','c' },{ 'D','d'},{ 'E','e' },{ 'F','f' },
{ 'G','g' },{ 'H','h' },{ 'I','i' },{ 'J','j' },{ 'K','k' },{ 'L','l' },
{ 'M','m' },{ 'N','n' },{ 'O','o' },{ 'P','p' },{ 'Q','q' },{ 'R','r' },
{ 'S','s' },{ 'T','t' },{ 'U','u' },{ 'V','v' },{ 'W','w' },{ 'X','x' },
{ 'Y','y' },{ 'Z','z' } };
Important note: Even though this line contains the =
symbol, it is not an assignment. This is a declaration. The difference between assignment and declaration is that in assignment you refer to a variable that already exists; in a declaration you are creating a variable as evinced by the type specifiers. In fact you can (and probalby should) omit the =
from this line. But I included it to make this point as you will see people using =
here.
As noted in comments, you will also need to change the line UppercaseConvert[character]
. The map::operator[]
can only be used on non-const maps because part of its behaviour is to add a new entry if the character did not already exist in the map.
The loop could be:
for (char character : word)
{
auto it = UppercaseConvert.find(character);
char ch = it == UppercaseConvert.end() ? character : it->second;
ConvertedString.push_back( ch );
}
If you also plan to look the map up in other places then it'd be a good idea to separate that lookup code into its own function.
Upvotes: 2