我已经告诉别人,编写using namespace std;代码是错误的,我应该用std::cout和std::cin直接代替.
为什么被using namespace std;认为是不好的做法?是低效还是冒着声明模糊变量(与名称std空间中的函数具有相同名称的变量)的风险?它会影响性能吗?
下面的程序在 C++20 中编译得很好:
#include <memory>
struct A{ virtual ~A() = default; };
struct B: A {};
int main()
{
std::shared_ptr<A> p = std::make_shared<B>();
auto x = dynamic_pointer_cast<A>(p);
}
Run Code Online (Sandbox Code Playgroud)
但是在 C++17 中它会产生一个错误:
<source>: In function 'int main()':
<source>:9:14: error: 'dynamic_pointer_cast' was not declared in this scope; did you mean 'std::dynamic_pointer_cast'?
9 | auto x = dynamic_pointer_cast<A>(p);
| ^~~~~~~~~~~~~~~~~~~~
| std::dynamic_pointer_cast
In file included from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/memory:77,
from <source>:1:
Run Code Online (Sandbox Code Playgroud)
你能告诉我在 C++20 中有什么改变使它工作吗?
考虑以下示例:
struct S {
template<typename T = void>
friend void foo(S) {
}
};
int main() {
S s;
foo(s); // (1)
foo<void>(s); // (2)
}
Run Code Online (Sandbox Code Playgroud)
我的 GCC 9.2.0 无法编译(2)并出现以下错误:
a.cpp: In function 'int main()':
a.cpp:10:5: error: 'foo' was not declared in this scope
10 | foo<void>(s);
| ^~~
a.cpp:10:9: error: expected primary-expression before 'void'
10 | foo<void>(s);
| ^~~~
Run Code Online (Sandbox Code Playgroud)
不过,(1)效果很好。为什么是这样?如何foo使用显式模板参数进行调用?
考虑以下示例:
namespace N {
template<class>
struct C { };
template<int, class T>
void foo(C<T>);
}
template<class T>
void bar(N::C<T> c) {
foo<0>(c);
}
int main() {
N::C<void> c;
bar(c);
}
Run Code Online (Sandbox Code Playgroud)
GCC和Clang的失败编译C ++下17个标准(本规范-Werror),因为(根据我的理解)在C ++ 17 ADL不明确时,模板参数不工作<...>存在(除非名称已确定为模板名称),因此foo是未找到的非依赖名称。
在 C++20 中,ADL 规则发生了变化,显式模板参数不会阻止 ADL。现在它似乎foo变成了一个应该可以通过 ADL 解析的依赖名称。但是,GCC 和 Clang 对这段代码的有效性有不同的看法。CLang 编译它没有错误,但 GCC (10.2, -std=c++2a) 抱怨:
error: 'foo' was not declared in this scope; did you mean 'N::foo'?
在 C++17 模式下,Clang 产生以下警告:
warning: use of function template …
c++ templates language-lawyer argument-dependent-lookup c++20