我喜欢完全在头文件中实现类,但我不喜欢在代码中添加std::
。
我认为在头文件中使用using namespace std
会很糟糕,因为这会污染所有下游源文件的命名空间。
所以我经常在头文件中做这样的事情:
class foo {
using std::vector;
// in this code I don't need to qualify vector with std::
}
但这似乎不适用于某些事情,例如std::unique_ptr
,std::invalid_argument
,std::move
。
我的需求是否有补救措施?
答案 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
语句,如果你多次使用相同的类型,那可能会有所帮助(事实上,你也可以使用全局,为多次使用的类型制作通用名称