在字符串常量之前缺少预期的标识符。

20

有这样一个程序:

#include <iostream>
#include <string>
using namespace std;
class test
{
public:
    test(std::string s):str(s){};
private:
    std::string str;
};

class test1
{
public:
    test tst_("Hi");
};

int main()
{
    return 1;
}

我执行

g++ main.cpp

时为什么会得到以下的结果?

main.cpp:16:12: error: expected identifier before string constant
main.cpp:16:12: error: expected ‘,’ or ‘...’ before string constant

1
你真的应该学会始终使用 g++ -Wall -g 进行编译。 - Basile Starynkevitch
-Wall: "Enable most warning messages." and -g: "Generate debug information in default format." or "generate debugging information" -- source: g++ -v --help - Milan
2个回答

25
您无法在声明变量时初始化tst_,这只适用于static const原始类型。相反,您需要为class test1编写一个构造函数。

编辑:下面是我在ideone.com中演示的可行示例。请注意我所做的一些更改。首先,最好让test的构造函数接受stringconst引用以避免复制。其次,如果程序成功,则应该使用return 0而不是1(使用return 1会在ideone中导致运行时错误)。

#include <iostream>
#include <string>
using namespace std;
class test
{
public:
    test(const std::string& s):str(s){};
private:
    std::string str;
};
 
class test1
{
public:
    test1() : tst_("Hi") {}
    test tst_;
};
 
int main()
{
    return 0;
}

你不能在声明tst_时初始化它。这只能用于static const原始类型。出于好奇,为什么不行?我的意思是,如果可以在声明时初始化tst_,会有什么问题吗?这是为了避免可能的错误行为吗?非常感谢! - Milan
我不能给出确切的原因,因为我不是这门语言的创建者。我不认为会发生什么不好的事情,但可能是因为这种实现方式更容易。 - Ivaylo Strandjev

1
有另一种更简单的方法来实现你想要的:只需将语句从test tst_("Hi");改为test tst_{"Hi"};,它就会起作用。下面是修改后的代码,它按预期工作。
#include <iostream>
#include <string>
using namespace std;
class test
{
public:
    test(std::string s):str(s){cout<<"str is: "<<s;}
private:
    std::string str;
};

class test1
{
public:
    test tst_{"Hi"};
};

int main()
{   test1 obj;
    return 0;
}

请注意,我刚刚将test tst_("Hi");更改为test tst_{"Hi"};,其他所有内容都完全相同。仅为确认它是否有效,我添加了一个cout来检查它是否正确初始化了str变量。我认为这个一行解决方案更加优雅(至少对我来说是这样),并且符合新标准。

为什么 test tst_{"Hi"} 能够正常工作,但是 test tst_("Hi") 却不能?您能否详细解释一下?非常感谢! - Milan
@Milan 当使用C++11中的类内初始化器时,我们可以使用{}但不能使用(). 在这里更详细地解释了相同的问题:为什么C++11类内初始化器不能使用括号?。还要注意,您可以找到许多其他SO帖子来解释相同的问题。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接