C ++标准库:如何编写cout,cerr,cin和endl的包装?
我不喜欢using namespace std
,但是我也厌倦了在每个cout
, cin
, cerr
和endl
前inputstd::
。 所以,我想给他们这样短的新名字:
// STLWrapper.h #include <iostream> #include <string> extern std::ostream& Cout; extern std::ostream& Cerr; extern std::istream& Cin; extern std::string& Endl; // STLWrapper.cpp #include "STLWrapper.h" std::ostream& Cout = std::cout; std::ostream& Cerr = std::cerr; std::istream& Cerr = std::cin; std::string _EndlStr("\n"); std::string& Endl = _EndlStr;
这工作。 但是,在上面我有什么问题吗? 有没有更好的方法来实现?
为什么不
using std::cin; using std::cout;
等等? 然后,在你的代码中,你可以使用cin
, cout
等等,而不会意外地将std
命名空间的其余部分注入到你的代码中。
亚历克斯已经给你一个答案如何在语法上解决这个问题。 但是,我想指出另外两个有关这个问题的论点:
-
不pipe你使用using指令 (
using namespace std
)还是using namespace std
更小的邪恶的姐妹, 使用声明 (using std::cout
),重载都可能导致令人讨厌的意外。 inputstd::
相比花费半个晚上的时间来debugging找出名为std::distance()
而不是你自己的distance()
函数的代码没有多大麻烦,只是因为你犯了一个小错误而std::distance()
意外地是一个更好的搭配。 -
一行代码被写入一次 ,但根据它的生命周期, 它被读取数十,数百甚至数千次 。 所以编写一行代码所花费的时间根本就不重要 , 重要的是只需要读取和解释一行代码 。 即使用合适的
std::
写入一行,要花费三倍的时间,如果读取速度只有10%,仍然是值得的。
所以重要的问题是: 是否更容易阅读和解释所有std::
的代码行或更难 ? 从另一个答案 :这里还有一个数据点:很多很多年以前,我也习惯于把标准库中的所有东西都加上前缀
std::
。 然后我在一个项目中工作,在这个项目中,开始时决定禁止using
指令和声明,除了函数作用域。 你猜怎么了? 我们大多数人花了几个星期的时间才开始写前缀,而且在几周之后,我们大部分人甚至一致认为它确实使代码更具可读性 。 (这是有原因的: 无论你喜欢更短还是更长的散文是主观的,但前缀客观地增加了代码的清晰度,不仅编译器,而且你也更容易看到引用哪个标识符。十年来,这个项目已经有了几百万行的代码。 由于这些讨论一次又一次地出现,我曾经很好奇在项目中实际使用(允许的)函数范围的频率。 我对它的来源进行了处理,只发现了一两个地方。 对我来说,这表明, 一旦尝试过,开发人员 即使在允许使用的情况下也没有发现
std::
painful 足够使用指令,甚至每100kLoC一次。我觉得很遗憾,你所能find的每一本书和教程都会跳过
std::
,因为这会让人习惯于以这种方式阅读代码。 当我教了几年C ++(上述经验之后)时,我告诉我的学生,我不想在代码中看到任何using
指令或声明。 (这个规则唯一的例外就是using std::swap
,BTW,为了让swap(a,b)
在命名空间std
之外select重载)。一旦他们习惯了,当问及它们时,他们说他们发现没有std::
前缀的代码混淆了。 有的甚至把std::
前缀添加到他们从没有它的书或教程中键入的代码 。
底线:打字std::
有什么困难,每个人都得到如此的努力呢? 现在我已经做了15年以上,我不会放过任何东西。