C ++风格问题:#include什么? [英] C++ style question: what to #include?

查看:95
本文介绍了C ++风格问题:#include什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑此翻译单位:

  #include< map& 
#include< string>
int main()
{
std :: map< std :: string,std :: size_t> mp;
mp.insert(std :: make_pair(hello,42));
}

这个翻译单元中有两件事情困扰着我,




  • std :: size_t

  • std :: make_pair



我刚刚假设< cstddef> < utility> 必须已经 #include d由< string> map>

这个假设是否合理?至少对于 make_pair 我认为有一个非常有力的保证,因为map成员接口使用 std :: pair 。对于 std :: size_t 没有正式的保证,但是它是非常非常非常可能,一旦你包括 map string 。风格问题一是 您是否明确包括< cstddef> < utility> 在此翻译单元中?



此部分部分涉及某些标题的不确定性。然而,有问题的第二部分。假设我们有这个

  // fh 
#ifndef BIG_F_GUARD
#define BIG_F_GUARD
# include< string>
std :: string f();
#endif

//f.cpp
#includefh
std :: string f()
{
std: :string s;
return s;
}

第二个问题是: code>< string> into f.cpp?

明确。 Btw。两个问题后面都有一个大的 WHY :)谢谢。

解决方案

在第一种情况下,我可能不会,但我应该,如果我想我的代码是正确的便携式。没有要求 map :: size_type size_t ,因此没有必要< map> 以包含 size_t 的定义。对于这个问题, size_t 可以是一个类型别名而不是一个不同的类型,因此即使 size_type size_t ,则不必在< map> 中使用该名称定义。正如你所说,很可能但不能保证< map> 包括< cstddef>



在第二种情况下,我绝对不会,因为我知道我不需要。 IMO a .cpp文件有权依赖于其相应的.h文件包含的头文件,因为您希望如果修改.h文件,您可能需要修改.cpp文件 - 更改接口意味着更改其实现,大部分时间。即使您认为我没有资格,我也可以随时 < string> $ < utility> 可以定义 std :: pair (因为它需要它)而不定义 std :: make_pair code>(这是来自相同的标准头,为了参数的缘故,我们说不需要定义< map> )。这将是可能的,如果< utility> 的实现版本本身包括一堆其他文件,对于不同的位和< map> / code>只是包括它需要的位。对头包含其他头的特定权限,但我不知道是否给头的特定权限放在命名空间 std 中,而不包括整个对应的标题。事实是,在实践中很难注意到你在这些情况下忘记了标准包含,因为实现不检查你,这就是为什么我知道在实践中我很可能不会这样做。幸运的是,任何移植到具有不同头依赖的实现的任何人都应该容易修复。


consider this translation unit:

#include <map>
#include <string>
int main()
{
   std::map<std::string, std::size_t> mp;
   mp.insert(std::make_pair("hello", 42)); 
}

There are two things in this translation unit that are bothering me, and they are

  • std::size_t
  • std::make_pair

I have just assumed that <cstddef> and <utility> must have been #included by <string> and <map>.
How rightful is this assumption? At least for make_pair I think there's a pretty strong guarantee because map member interfaces use std::pair. For std::size_t there is no formal guarantee but still it is very very very likely that it is available as soon as you include map or string. The stylistic question number one is Would you explicitly include <cstddef> and <utility> in this translation unit?

This part partly deals with the uncertaintly of some header being already included. However, there's the second part of the question. Suppose we have this

//f.h
#ifndef BIG_F_GUARD
#define BIG_F_GUARD
#include <string>
std::string f();
#endif   

//f.cpp
#include "f.h"
std::string f()
{
    std::string s;
    return s;
}

Second question is: Would you explicitly #include <string> into f.cpp?

I think I made my question clear. Btw. both questions are followed by a big WHY :) Thanks.

解决方案

In the first case, I probably wouldn't but I should, if I want my code to be properly portable. There's no requirement that map::size_type is size_t, so there's no necessity for <map> to include a definition of size_t. For that matter, size_t can be a type alias rather than a distinct type, so even if size_type is size_t, it needn't have been defined in <map> using that name. So as you say, it's likely but not guaranteed that <map> includes <cstddef>.

In the second case, I definitely wouldn't, because I know I don't need to. IMO a .cpp file is entitled to rely on the headers included by its corresponding .h file, since you kind of expect that if you modify the .h file you potentially need to modify the .cpp file too -- change an interface implies change its implementation, most of the time. And even if you feel I'm not entitled, I can always document that f.h includes <string>, in which case I can rely on that.

Regarding <utility>, I don't know whether <map> is allowed to define std::pair (because it needs it) without defining std::make_pair (which is from the same standard header, and for the sake of argument let's say it isn't needed to define <map>). This would be possible if the implementation's version of <utility> itself includes a bunch of other files, for different bits, and <map> just includes the bit it needs. Specific permission is given for headers to include other headers, but I don't know whether specific permission is given for headers to put things in namespace std without including the whole of the corresponding header. The thing is, in practice it is very difficult to notice that you've forgotten a standard include in these cases, because implementations don't check for you, and that's why I know that in practice I'd quite likely not do it. Luckily it should be any easy fix for anyone porting to an implementation with different header dependencies.

这篇关于C ++风格问题:#include什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆