C++空字符串构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/925513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ empty String constructor
提问by George
I am a C++ beginner, so sorry if the question is too basic.
我是 C++ 初学者,如果问题太基本,请见谅。
I have tried to collect the string constrcturs and try all them out (to remember them).
我试图收集字符串 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;
All of them works except for the strA. It prints "1". Why? Whats the type of the strA in this case? How can I check the type of stuff when I am unsure?
除了strA之外,所有这些都有效。它打印“1”。为什么?在这种情况下 strA 的类型是什么?当我不确定时,如何检查物品的类型?
I have noticed that the correct way is this (which by the way seems to be inconsistent with the other constructors, sometimes parens sometimes no parens):
我注意到正确的方法是这样的(顺便说一句,这似乎与其他构造函数不一致,有时括号有时没有括号):
string strA;
ps: question in bold, usual irrelevant answers will be downvoted.
ps:问题以粗体显示,通常不相关的答案将被否决。
回答by Tadeusz Kopec
This is a very popular gotcha. C++ grammar is ambiguous. One of the rules to resolve ambiguities is "if something looks like declaration it is a declaration". In this case instead of defining a variable you declared a function prototype.
这是一个非常受欢迎的陷阱。C++ 语法有歧义。解决歧义的规则之一是“如果某事看起来像声明,它就是声明”。在这种情况下,您声明了一个函数原型,而不是定义一个变量。
string strA();
is equivalent to
相当于
string strA(void);
a prototype of a no-arg function which returns string.
返回字符串的无参数函数的原型。
If you wish to explicitly call no-arg constructor try this:
如果您希望显式调用 no-arg 构造函数,请尝试以下操作:
string strA=string();
It isn't fully equivalent - it means 'create a temporary string using no-arg constructor and then copy it to initialize variable strA', but the compiler is allowed to optimize it and omit copying.
它并不完全等效——它意味着“使用无参数构造函数创建一个临时字符串,然后将其复制到初始化变量 strA”,但允许编译器对其进行优化并省略复制。
回答by C?t?lin Piti?
It considers
它认为
string strA();
as a function declaration.
作为函数声明。
For default constructor use:
对于默认构造函数使用:
string strA;
回答by C?t?lin Piti?
In C++, as in C, there is a rule that says that anything that looks like a declarartion will be treated as a declaration.
在 C++ 中,就像在 C 中一样,有一条规则规定,任何看起来像声明的东西都将被视为声明。
string strA();
looks like a function declaration, so it is treated as one. You need:
看起来像一个函数声明,所以它被视为一个。你需要:
string strA;
回答by Johannes Schaub - litb
I don't think that in this case, the rule "if it could be a declaration, it's taken to be a declaration" applies. Since in the following, boththings are declarations
我不认为在这种情况下,“如果它可以是声明,则被视为声明”的规则不适用。因为在下面,两件事都是声明
string a;
string a();
The one is the declaration of an object, and the other is the declaration of a function. The rule applies in other cases. For example, in this case:
一个是对象的声明,另一个是函数的声明。该规则适用于其他情况。例如,在这种情况下:
string a(string());
In that case, string()
can mean two things.
在这种情况下,string()
可能意味着两件事。
- Declaration of an unnamed function parameter
- Expression creating a default constructed
string
- 未命名函数参数的声明
- 创建默认构造的表达式
string
The fule applies here, and string()
is taken to mean the same as the following, named parameter (names are irrelevant in parameters when declaring a function)
fule 在这里适用,并被string()
认为与以下命名参数相同(在声明函数时,名称与参数无关)
string a(string im_not_relevant());
If a function takes as parameter an array or another function, that parameter decays into a pointer. In case of a function parameter, to a pointer to the function. Thus, it is equivalent to the following, which may look more familiar
如果函数将数组或其他函数作为参数,则该参数会衰减为指针。在函数参数的情况下,指向函数的指针。因此,它等效于以下内容,可能看起来更熟悉
string a(string (*im_not_relevant)());
But in your case, it's rather the syntax that's getting into the way. It's saying that the following is a function declaration. It can never be the declaration of an object (even though that was probably intended by the programmer!)
但在你的情况下,它是进入方式的语法。据说以下是函数声明。它永远不可能是一个对象的声明(即使这可能是程序员的本意!)
string a();
So there is no ambiguity in this context in the first place, and thus it declares a function. Since string
has a user defined constructor, you can just omit the parentheses, and the effect remains the same as what was intended.
所以首先在这个上下文中没有歧义,因此它声明了一个函数。因为string
有一个用户定义的构造函数,你可以省略括号,效果和预期的一样。
回答by laalto
It prints 1
because pointers to functions are always converted to numeric as true
.
它打印1
是因为指向函数的指针总是转换为数字 as true
。
回答by MSalters
tkopec is right on why it doesn't work. To answer your second question, here's how you check the type:
tkopec 是正确的为什么它不起作用。要回答您的第二个问题,以下是您检查类型的方法:
template<typename TEST> void Error_() {
TEST* MakeError = 1;
}
By calling Error_(StrA);
you will get a compile error, and your compiler will probably tell you that it happened in Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void))
Now, std::basic_string > is just std::string, so this really means Error_< std::string (*)(void)> (std::string (*)(void))
. The part between '<>' is repeated between '()', and that's the sype of strA. In this case, std::string (*)(void)
.
通过调用Error_(StrA);
你会得到一个编译错误,你的编译器可能会告诉你它发生在Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void))
现在,std::basic_string> 只是 std::string,所以这真的意味着Error_< std::string (*)(void)> (std::string (*)(void))
. '<>' 之间的部分在 '()' 之间重复,这就是 strA 的类型。在这种情况下,std::string (*)(void)
。
回答by Naveen
Compiler interprets string strA()
as a function prototype of a function which takes void arguments and returns an object of string type. If you want to create a empty string object use string strA;
(without paranthesis)
编译器将其解释string strA()
为函数的函数原型,该函数采用 void 参数并返回字符串类型的对象。如果要创建空字符串对象使用string strA;
(不带括号)