我是C ++初学者,如果问题太基础,那就很抱歉。
我试图收集字符串constrcturs并尝试所有它们(记住它们)。
string strA(); // string(); empty string // incorrect
string strB("Hello"); // string( const char* str)
string strC("Hello",3); // string( const char* str, size_type length)
string strD(2,'c'); // string( size_type lenght, const char &c)
string strE(strB); // string( const string& s)
cout << strA << endl;
cout << strB << endl;
cout << strC << endl;
cout << strD << endl;
cout << strE << endl;
除 strA 外,所有这些都有效。它打印“1”。 为什么?在这种情况下,strA的类型是什么?当我不确定时,如何检查东西的类型?
我注意到这是正确的方式(顺便说一句,这似乎与其他构造函数不一致,有时候parens有时没有parens):
string strA;
ps:大胆的问题,通常不相关的答案将被低估。
答案 0 :(得分:32)
这是一个非常受欢迎的问题。 C ++语法含糊不清。解决歧义的规则之一是“如果某些事情看起来像宣言那就是宣言”。在这种情况下,您不是定义变量,而是声明了函数原型。
string strA();
相当于
string strA(void);
返回字符串的无参数函数的原型。
如果你想显式调用no-arg构造函数,试试这个:
string strA=string();
它不完全等效 - 它意味着'使用no-arg构造函数创建一个临时字符串,然后将其复制到初始化变量strA',但允许编译器对其进行优化并省略复制。
答案 1 :(得分:13)
考虑
string strA();
作为函数声明。
对于默认构造函数使用:
string strA;
答案 2 :(得分:6)
在C ++中,就像在C中一样,有一条规则说任何看起来像声明的东西都会被视为声明。
string strA();
看起来像一个函数声明,所以它被视为一个。你需要:
string strA;
答案 3 :(得分:4)
我不认为在这种情况下,“如果它可以是声明,它被视为声明”的规则适用。因为在下面,两个事物都是声明
string a;
string a();
一个是对象的声明,另一个是函数的声明。该规则适用于其他情况。例如,在这种情况下:
string a(string());
在这种情况下,string()
可能意味着两件事。
string
这里的fule适用,string()
与下面的命名参数相同(在声明函数时名称与参数无关)
string a(string im_not_relevant());
如果函数将数组或其他函数作为参数,则该参数会衰减为指针。在函数参数的情况下,指向函数的指针。因此,它等同于以下,可能看起来更熟悉
string a(string (*im_not_relevant)());
但是在你的情况下,它更像是语法。它说以下是函数声明。它永远不会是对象的声明(即使这可能是程序员想要的!)
string a();
因此,首先在这个上下文中没有歧义,因此它声明了一个函数。由于string
具有用户定义的构造函数,因此您可以省略括号,并且效果与预期的相同。
答案 4 :(得分:3)
它打印1
因为指向函数的指针总是转换为数字true
。
答案 5 :(得分:2)
tkopec是正确的,为什么它不起作用。要回答第二个问题,请按以下方式检查类型:
template<typename TEST> void Error_() {
TEST* MakeError = 1;
}
通过调用Error_(StrA);
,您将收到编译错误,编译器可能会告诉您它发生在Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void))
现在,std :: basic_string&gt;只是std :: string,所以这真的意味着Error_< std::string (*)(void)> (std::string (*)(void))
。 '&lt;&gt;'之间的部分在'()'之间重复,这就是strA的类型。在这种情况下,std::string (*)(void)
。
答案 6 :(得分:1)
编译器将string strA()
解释为函数的函数原型,该函数接受void参数并返回字符串类型的对象。如果要创建空字符串对象,请使用string strA;
(没有paranthesis)