命名空间信息损害了 C++ 的可读性
Namespace information compromises the readability in C++
我是 C++
的新手,有 C
的背景。对我来说很难采用的一件事是经常使用范围运算符,例如std::
好吧,我会通过将 using namespace std
放在我的源代码的开头来避免使用它,但是很多人不使用这种方法,因为他们认为这可能会在将来咬到他们。
此外,visual-studio
还显示 error/warning 范围运算符的消息,例如
cannot convert from 'std::vector<int,std::allocator<_Ty>> *' to 'std::shared_ptr<std::vector<int,std::allocator<_Ty>>>'
虽然上面的信息很冗长,但是读起来很痛苦(?)。我觉得如果是这种形式的话可以读起来很简单
cannot convert from 'vector<int,allocator<_Ty>> *' to 'shared_ptr<vector<int,allocator<_Ty>>>'
1) 为什么每个人都在使用 std::
,即使是 cout
、cin
、endl
?为什么会有人将这些标签用于其他目的?
2) 他们在 Visual studio 中的解决方法是不向我显示带有前缀 std::
的 error/messages/syntax-highlights 吗?
尽管如评论中所指出的那样,using namespace std;
之类的代码是 considered bad practice,但您可以通过指定 [=] 来避免在 std::cout
之类的代码中重复使用名称空间前缀using
语句中的 22=] 个 个作用域元素。
像这样:
using std::cout; //
using std::cin; // You can, from then on, just use 'cout', 'cin' and 'endl'
using std::endl; //
对于非常常见的元素,如上面代码中列出的元素,您可以将相关的using
行放在头文件中——通常,您的'global' 用于构建预编译头文件的头文件。
对于初学者来说,限定名称和非限定名称的名称查找有所不同。
例如考虑以下程序。
#include <iostream>
class A
{
private:
int x = 10;
public:
operator int() const { return x; }
friend void f( const A & )
{
std::cout << "f( const A & )\n";
}
};
void f( int )
{
std::cout << "f( int )\n";
}
int main()
{
const A a;
f( a );
::f( a );
return 0;
}
程序输出为
f( const A & )
f( int )
其次使用 using 指令可能会导致名称冲突或由于重载解析而选择错误的函数。
除此之外,代码的可读性可能较差,因为 reader 不知道 endl
是 std::endl
还是在包含的某个命名空间中定义的用户定义函数由于大量使用指令,在名称查找中。
有些情况下您需要使用显式或隐式 using 指令。
例如,如果您想使用来自命名空间的声明 std::placeholders
,或者当您想要声明一个内联命名空间时。但是这些指令的范围通常非常有限。另一个例子是使用 using 声明。但是再次尝试使它们的范围尽可能小。
在有限范围内,例如在函数内,使用 using namespace std
或任何其他 using
.
是合乎逻辑的
重复命名空间名称是乏味的,但您可以免费避免它。我看到很多代码都充斥着 std::
,尤其是涉及到 std::forward、std::move、std::function、std::thread 等的用法时
像 using
这样的 C++ 关键字是有原因的;无条件的说"using namespace std is bad"是错误的
回答你的2)
,我相信答案是"No, there's no way to change the way VS writes out error messages to strain out all the std::
"。
好消息是这些错误消息过去更糟糕。您会收到针对给定模板的所有 N 个变体的错误消息,然后必须从噪声海洋中解析出微小的信号规格。不好玩。如果您使用像 std::vector<std::vector<std::string> > >
这样的嵌套模板,上帝会帮助您。
因此,虽然模板错误消息仍然有点冗长,但显示的信息是实际信息,而不是垃圾邮件垃圾邮件鸡蛋和没有鸡蛋的垃圾邮件。
哦,>>
过去总是解析为流运算符,因此您必须在嵌套模板的 >
之间添加空格。 上山,双向!!!
我是 C++
的新手,有 C
的背景。对我来说很难采用的一件事是经常使用范围运算符,例如std::
好吧,我会通过将 using namespace std
放在我的源代码的开头来避免使用它,但是很多人不使用这种方法,因为他们认为这可能会在将来咬到他们。
此外,visual-studio
还显示 error/warning 范围运算符的消息,例如
cannot convert from 'std::vector<int,std::allocator<_Ty>> *' to 'std::shared_ptr<std::vector<int,std::allocator<_Ty>>>'
虽然上面的信息很冗长,但是读起来很痛苦(?)。我觉得如果是这种形式的话可以读起来很简单
cannot convert from 'vector<int,allocator<_Ty>> *' to 'shared_ptr<vector<int,allocator<_Ty>>>'
1) 为什么每个人都在使用 std::
,即使是 cout
、cin
、endl
?为什么会有人将这些标签用于其他目的?
2) 他们在 Visual studio 中的解决方法是不向我显示带有前缀 std::
的 error/messages/syntax-highlights 吗?
尽管如评论中所指出的那样,using namespace std;
之类的代码是 considered bad practice,但您可以通过指定 [=] 来避免在 std::cout
之类的代码中重复使用名称空间前缀using
语句中的 22=] 个 个作用域元素。
像这样:
using std::cout; //
using std::cin; // You can, from then on, just use 'cout', 'cin' and 'endl'
using std::endl; //
对于非常常见的元素,如上面代码中列出的元素,您可以将相关的using
行放在头文件中——通常,您的'global' 用于构建预编译头文件的头文件。
对于初学者来说,限定名称和非限定名称的名称查找有所不同。
例如考虑以下程序。
#include <iostream>
class A
{
private:
int x = 10;
public:
operator int() const { return x; }
friend void f( const A & )
{
std::cout << "f( const A & )\n";
}
};
void f( int )
{
std::cout << "f( int )\n";
}
int main()
{
const A a;
f( a );
::f( a );
return 0;
}
程序输出为
f( const A & )
f( int )
其次使用 using 指令可能会导致名称冲突或由于重载解析而选择错误的函数。
除此之外,代码的可读性可能较差,因为 reader 不知道 endl
是 std::endl
还是在包含的某个命名空间中定义的用户定义函数由于大量使用指令,在名称查找中。
有些情况下您需要使用显式或隐式 using 指令。
例如,如果您想使用来自命名空间的声明 std::placeholders
,或者当您想要声明一个内联命名空间时。但是这些指令的范围通常非常有限。另一个例子是使用 using 声明。但是再次尝试使它们的范围尽可能小。
在有限范围内,例如在函数内,使用 using namespace std
或任何其他 using
.
重复命名空间名称是乏味的,但您可以免费避免它。我看到很多代码都充斥着 std::
,尤其是涉及到 std::forward、std::move、std::function、std::thread 等的用法时
像 using
这样的 C++ 关键字是有原因的;无条件的说"using namespace std is bad"是错误的
回答你的2)
,我相信答案是"No, there's no way to change the way VS writes out error messages to strain out all the std::
"。
好消息是这些错误消息过去更糟糕。您会收到针对给定模板的所有 N 个变体的错误消息,然后必须从噪声海洋中解析出微小的信号规格。不好玩。如果您使用像 std::vector<std::vector<std::string> > >
这样的嵌套模板,上帝会帮助您。
因此,虽然模板错误消息仍然有点冗长,但显示的信息是实际信息,而不是垃圾邮件垃圾邮件鸡蛋和没有鸡蛋的垃圾邮件。
哦,>>
过去总是解析为流运算符,因此您必须在嵌套模板的 >
之间添加空格。 上山,双向!!!