简体   繁体   English

涉及 iostream 和 wstring 的奇怪行为 C++

[英]Strange C++ behaviour involving iostream and wstring

I have two files, my_program.cpp and its header my_program.h .我有两个文件, my_program.cpp和它的 header my_program.h

my_program.cpp contains only this: my_program.cpp包含这个:

#include "my_program.h"
using namespace std;

my_program.h contains a pointer to a function which returns a wstring , as follows: my_program.h包含一个指向 function 的指针,它返回一个wstring ,如下所示:

using namespace std;
typedef wstring (*my_function)(wstring, int, int, int, int);

The program doesn't compile in this state (stops at typedef... saying that ISO C++ forbids declaration of 'wstring' with no type) but if I add #include <iostream> before #include "my_program.h" in the.cpp file, the program miraculously compiles.该程序不会在此 state 中编译(在 typedef 处停止...说 ISO C++ 禁止声明没有类型的 'wstring')但是如果我在#include "my_program.h"之前添加#include <iostream> 。 cpp 文件,程序奇迹般地编译。

Why does this happen?为什么会这样? I just hope I didn't make a foolish mistake and I'm now going to be laughed at.我只是希望我没有犯一个愚蠢的错误,我现在会被嘲笑。

You really should include <string> .你真的应该包括<string>

From the sound of things, your compiler's <iostream> happens to include <string> , so it works, but on a different compiler it may not.从事物的声音来看,您的编译器的<iostream>恰好包含<string> ,因此它可以工作,但在不同的编译器上它可能不会。 C++ allows a standard header to include other standard headers, but doesn't require it. C++ 允许标准 header 包含其他标准标头,但不要求它。 In some cases, you get only a declaration of the class, so some things work, and others don't.在某些情况下,您只会得到 class 的声明,因此有些事情有效,有些则无效。

At least in my experience, this is also an issue that's likely to change from one version of a compiler to the next, so even if you don't intend to port to anything else, your code may quit working just due to a seemingly trivial upgrade unless you include the right header.至少根据我的经验,这也是一个可能会从一个版本的编译器更改为下一个版本的问题,因此即使您不打算移植到其他任何版本,您的代码也可能会因为看似微不足道的问题而停止工作升级除非你包括正确的 header。

Before you add #include <iostream> , the compiler has no idea what wstring is -- hence the error在添加#include <iostream>之前,编译器不知道wstring是什么——因此出现错误

After you include the iostream header, (which defines std::wstring -- possibly via other headers it includes), the compiler knows what wstring refers to and can properly parse the typedef .在包含 iostream header(它定义std::wstring —— 可能通过它包含的其他标头)之后,编译器知道wstring指的是什么并且可以正确解析typedef

One thing to keep in mind is that the compiler only cares about what's called the compilation unit (.cpp files), not the headers;要记住的一件事是,编译器只关心所谓的编译单元(.cpp 文件),而不关心头文件; the headers come into play when a compilation unit includes them (think of verbatim copy-paste).当编译单元包含标题时,标题就会发挥作用(想想逐字复制粘贴)。 Therefore you can include iostream (or as others pointed out <string> ) anywhere before the typedef , to make it work -- from this perspective, including it before the header counts the same as including it at the first line of the header.因此,您可以在typedef之前的任何位置包含iostream (或其他人指出的<string> ),以使其正常工作——从这个角度来看,在 header 之前包含它与在 header 的第一行包含它的计数相同。

It is generally a good idea, however, to make headers as self consistent as possible (so in your case include the relevant headers in your header, instead of the.cpp), so the includers do not need to remember what other headers to include as well to make it work as intended.但是,使标头尽可能保持一致通常是个好主意(因此在您的情况下,将相关标头包含在 header 中,而不是 .cpp 中),因此包含程序不需要记住要包含的其他标头以及使其按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM