无法将 Map 声明和分配为 const

Can't Declare and Assign Map as const

我刚刚删除了一个设置为 4 小时未回答的问题。通过反复试验,我基本上能够自己回答这个问题,而且除了一件之外,我似乎对它有很好的处理。为什么我不能将我的地图声明为常量或者我做错了?完整的例子在底部。

在 class header

const std::map <char, char> UppercaseConvert;

在class构造函数中

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' } };

如果我从声明和定义中删除 const,它将编译并工作,所以这不是世界末日。但是,既然这应该是静态的,它不应该是 const 类型吗?

这是它用在的函数:

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;
}

编辑:除非删除常量,否则无法编译的完整示例:

#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;
}

const UppercaseConvert = 是语法错误。当你引用一个已经存在的变量时,你只需使用它的名字,UppercaseConvert 在这里。您不要重复其声明或限定符的某些部分。


我们来谈谈台词:

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' } };

这叫做赋值。您正在将 UppercaseConvert 已有的值更改为不同的值。

所以,不可能让 UppercaseConvert 成为 const 并且也有这条线。因为如果它是 const 那么你不能改变它的值。

我猜你打算做的是初始化 UppercaseConvertinitialize 意味着提供一个值,变量在创建时将保留该值。到目前为止你写的方式,变量被初始化为一个空映射,你稍后尝试更改映射以在其中包含条目。构造函数体在成员变量初始化完成后运行。

Link to further reading about initialization for non-static members

在评论中,您似乎还希望地图是静态的。可能是个好主意。对于 static 成员,您无需在构造函数中放置任何内容。这是因为构造函数用于构造 class 的实例。但是静态成员不与任何特定实例相关联。静态成员意味着该成员总共只有一个实例。

class 定义应包含:

static const std::map<char, char> UppercaseConvert;

然后在 .cpp 文件中实现这个 class,但是 在任何函数之外 ,你用初始化器编写定义(并且你不要在这里重复单词 static):

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' } };

重要说明:尽管这一行包含 = 符号,但它 不是 赋值。这是一个宣言。赋值和声明之间的区别在于,在赋值中你引用了一个已经存在的变量;在声明中,您正在创建一个由类型说明符证明的变量。事实上,您可以(并且 probalby 应该)从这一行中省略 = 。但我把它包括在内是为了说明这一点,因为你会看到人们在这里使用 =


如评论中所述,您还需要更改行 UppercaseConvert[character]map::operator[] 只能用于非常量映射,因为它的部分行为是在映射中不存在该字符时添加一个新条目。

循环可以是:

for (char character : word)
{
    auto it = UppercaseConvert.find(character);
    char ch = it == UppercaseConvert.end() ? character : it->second;
    ConvertedString.push_back( ch );
}

如果您还计划在其他地方查找地图,那么最好将该查找代码分离到它自己的函数中。