类中vector的初始化问题

微信公众号:编程笔记本
微信公众号:编程笔记本
微信公众号:编程笔记本

点击上方蓝字关注我,我们一起学编程
欢迎小伙伴们分享、转载、私信、赞赏

今天分享一个在类中使用 vector 并初始化的小 trick 。

事情的起因是这样的:

在做牛客网的在线编程题时,一个小伙伴问我:“为什么我这里会报错啊?”

题目:

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g" 。当从该字符流中读出前六个字符 "google" 时,第一个只出现一次的字符是 "l" 。如果当前字符流没有存在出现一次的字符,返回 "#" 字符。

class Solution
{
public:
    string str;
    int index = 0;
    vector<int> hash(256, 0);

    //Insert one char from stringstream
    void Insert(char ch)
    {
        str.push_back(ch);
        ++hash[ch];
    }

    //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        for (int i = index; i < str.size(); ++i) {
            if (hash[str[i]] == 1) {
                index = i;
                return str[i];
            }
        }
        
        return '#';
    }

};

/*
编译信息:

./Solutin.h:6:22: error: expected parameter declarator
vector hash(256, 0);
^
*/

错误提示的意思是说,在 vector hash(256, 0);缺少参数声明

乍一看,我也不知所以,有点怀疑人生:难道我每天都在用的 vector 初始化还有两副面孔?

微信公众号:编程笔记本
微信公众号:编程笔记本
微信公众号:编程笔记本

是不是在类中不能对 vector 进行初始化呢?带着疑问,我将代码做了如下修改:

class Solution
{
public:
    string str;
    int index = 0;
    vector<int> hash;

    //Insert one char from stringstream
    void Insert(char ch)
    {
        hash.reverse(256);
        str.push_back(ch);
        ++hash[ch];
    }
    
    //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        for (int i = index; i < str.size(); ++i) {
            if (hash[str[i]] == 1) {
                index = i;
                return str[i];
            }
        }
        
        return '#';
    }

};

果不其然,这样编译通过了。

但我还是不甘心,这么好用的初始化凭什么不让我用?我不管,我就要这么用!!!编译器可不惯着我!没办法,只能另辟蹊径。

就在这时,脑海里想起了第二种 vector 的初始化方式:vector<int> a = vector<int>(256, 0); ,于是又对代码进行了修改:

class Solution
{
public:
    string str;
    int index = 0;
    vector<int> hash = vector<int>(256, 0);

    //Insert one char from stringstream
    void Insert(char ch)
    {
        str.push_back(ch);
        ++hash[ch];
    }
    
    //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        for (int i = index; i < str.size(); ++i) {
            if (hash[str[i]] == 1) {
                index = i;
                return str[i];
            }
        }
        
        return '#';
    }

};

果然,这样也编译通过了。再换一种初始化方式:vector<int> a{vector<int>(256, 0)}; 也能通过编译。

小沈阳:这是为什么呢?

微信公众号:编程笔记本
微信公众号:编程笔记本
微信公众号:编程笔记本

后来,查阅资料发现了问题所在。

原来,vector<int> hash(256, 0) 这种初始化方式,被编译器错误地认定为“函数定义”*,反观错误提示(缺少参数声明)就更加明显了。*

编译器认为:你正在定义一个成员函数,函数名为 hash ,返回值类型为 vector<int> ,函数有两个参数。但是参数的给定方式有错误,应该包含完整的参数声明。

所以编译器给出了这样的错误提示:

./Solutin.h:6:22: error: expected parameter declarator
vector hash(256, 0);
^

为了验证确实是这么回事,我写了一个测试案例:

#include <bits/stdc++.h>

using namespace std;

class A {
public:
    int func(10, 10);
};

int main()
{  
    return 0;
}

我将成员函数定义中的参数声明去掉,模拟前面的情况。果然。编译器给出了相同的错误提示:

./test.cpp:7:14: error: expected parameter declarator
int func(10, 10);
^

至于其他两种初始化方式不会报错的原因是,不会引起二义性。

以上,就是这个小 trick 的全部内容,最后鸣谢发现问题的袁文定同学。

微信公众号:编程笔记本
微信公众号:编程笔记本
微信公众号:编程笔记本

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页