如何避免使用std ::乱丢头文件

时间:2015-11-24 07:36:08

标签: c++ namespaces

我喜欢完全在头文件中实现类,但我不喜欢在代码中添加std::

我认为在头文件中使用using namespace std会很糟糕,因为这会污染所有下游源文件的命名空间。

所以我经常在头文件中做这样的事情:

class foo {
    using std::vector;
    // in this code I don't need to qualify vector with std::
}

但这似乎不适用于某些事情,例如std::unique_ptrstd::invalid_argumentstd::move

我的需求是否有补救措施?

2 个答案:

答案 0 :(得分:3)

使用std::没有错。事实上,我发现我的自我阅读代码由其他人编写,当我看到类似stack stk;的内容时,它让我想知道stack是否是标准的。因此,我建议使用它,因为虽然你输入了5个以上的字符,但它使你的代码对其他编码器更具可读性。

现在,为什么你尝试过的东西不起作用。它并不是因为C ++不允许它。根据标准草案 7.3.4 / p1使用指令[namespace.udir] Emphasis Mine ):

  

using-directive不应出现在类范围中,但可能出现在命名空间范围或块范围内。 [注意:查找时   using-directive中的namespace-name,只有名称空间名称   考虑,见3.4.6。 - 结束说明]可选   attribute-specifier-seq属于using-directive。

以上引用证明了为什么你不能这样做:

class Foo {
  using namespace std;
};

你不能这样做:

class Foo {
  using std::vector;
};

因为std::vector是模板类(即需要<T>)。

同样来自标准草案 7.3.3 / p5使用声明[namespace.udecl]:

  

using-declaration不得命名template-id。

禁止你这样做:

class Foo {
  using std::vector<int>;
};

如果这个&#34;困扰&#34;你可以做什么?你这么多将所有代码放在命名空间中并拖动using namespace std;

namespace mine {
  using namespace std;

  struct foo {
    unique_ptr<int> ptr;
  };
}

然而,当您执行std时,这不会让您免于拖动using namespace mine;命名空间。

如果您的编译器支持C ++ 11,则另一个选项是创建模板别名:

struct Foo {
  template<typename T>
  using unique_ptr = std::unique_ptr<T>;
  unique_ptr<int> ptr;
};

答案 1 :(得分:1)

我的建议仍然是养成在需要时随时随地使用std::的习惯。把它写出来是件好事,也不是坏事。

我将所有内容“放在一个文件中”,但这应该作为标题或一个文件解决方案:

#include <memory>
#include <vector>
#include <stdexcept>

using std::vector;
using std::invalid_argument;
using std::unique_ptr;

class foo
{

public:
    foo(int x)
    {
        if (x > 100) throw invalid_argument("too big");
        iv.push_back(x);
    }

private:
    vector<int> iv;
    unique_ptr<int> ip;
};

int main()
{
    foo bar(32);
}

类中的using允许您以不同的方式编写typedef(有人说“更具可读性”):

using vector_int = std::vector<int>;

引用(例如)不同类的构造函数:

class BasicTypeDecl : public TypeDecl
{
public:
    using TypeDecl::TypeDecl;
    ...
};

有了这些“知识”,我们可以提出:

#include <memory>
#include <vector>
#include <stdexcept>


class foo
{

public:
    using intvec=std::vector<int>;
    using intup = std::unique_ptr<int>;

    foo(int x)
        {
            using std::invalid_argument;
            if (x > 100) throw invalid_argument("too big");
            iv.push_back(x);
        }

private:
    intvec iv;
    intup ip;
};

int main()
{
    foo bar(32);
}

那里有std::invalid_argument,但其他类型的别名是using语句,如果你多次使用相同的类型,那可能会有所帮助(事实上,你也可以使用全局,为多次使用的类型制作通用名称