【发布时间】:2019-11-27 12:28:17
【问题描述】:
假设我有以下(非常简单的)代码。
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
这在 g++ 和 clang 上都能正常编译;但是,它无法在 MSVC 上编译并出现以下错误:
错误 C2039:“stoi”:不是“std”的成员
错误 C3861:“stoi”:找不到标识符
我知道std::stoi 是<string> 标头的一部分,这可能是前两个编译器包含在<iostream> 中的一部分,而后者没有。根据C++标准[res.on.headers]
一个 C++ 头文件可能包含其他 C++ 头文件。
对我来说,这基本上说明所有三个编译器都是正确的。
当我的一个学生提交作业时出现此问题,TA 将其标记为未编译;我当然去修了。但是,我想防止以后发生这样的事件。那么,有没有办法确定应该包含哪些头文件,而不是每次都在三个不同的编译器上编译来检查?
我能想到的唯一方法是确保对于每个std 函数调用,都存在适当的包含;但是,如果您有数千行长的现有代码,则搜索起来可能很乏味。是否有更简单/更好的方法来确保交叉编译器的兼容性?
三个编译器的例子:https://godbolt.org/z/kJhS6U
【问题讨论】:
-
如果您记得
std::stoi用于处理字符串,您可能会猜到<string>将是一个很好的包含标题。或者你可以搜索a good reference,它会告诉你。而且我建议您始终明确地包含头文件,这样您就不必依赖非可移植实现特定的行为。 -
最好的方法是在去任何其他平台之前去cppreference。他们那里有非常详细的东西。
-
在您编写代码时包含适当的标题。 IE。当您编写包含
std::stoi的代码时,您会立即确保#include <string>也存在。 -
一般情况下这是difficult problem。然而,当我们谈论缺少标准库包含时,通常的方法确实是检查所有使用的函数调用/类型。
-
@skratchi.at,学生们被告知他们可以使用他们想要的任何编译器,只要他们的代码符合标准。 4 年后,这是第一次成为问题。
标签: c++