如果我有一个名称空间,如:
namespace MyApp.Providers
{
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着如果我创建具有相同命名空间的其他文件和类,则共享using语句,并且我不需要再次包含它们?
如果是的话,这不是一个管理上的头疼吗?
在MSDN上,我可以阅读它的功能,但我想知道它在技术上做了什么(告诉编译器在哪里寻找类型......)?我的意思是用作指令.
我有两个用于ADL的片段用于演示目的.这两个片段都是由VC10,gcc和comeau C++编译器编译的,结果对于这三个片段都是相同的.
<1> ADL反对使用用户定义的命名空间的指令:
#include <algorithm>
namespace N
{
struct T {};
void swap(T,T) {}
}
namespace M
{
void swap(N::T,N::T) {}
}
int main()
{
using M::swap;
N::T o1,o2;
swap(o1,o2);
}
Run Code Online (Sandbox Code Playgroud)
编译结果:
error C2668: 'M::swap' : ambiguous call to overloaded function
could be 'void M::swap(N::T,N::T)'
or 'void N::swap(N::T,N::T)' [found using argument-dependent lookup]
Run Code Online (Sandbox Code Playgroud)
这是预期的,因为ADL不优先于正常查找结果加上ADL不是二等公民,ADL搜索结果与正常(非ADL)无法定义查找联合.这就是为什么我们有歧义.
<2> ADL反对使用std命名空间的指令:
#include <algorithm>
namespace N
{
struct T {};
void swap(T,T) {} //point 1
}
namespace M
{
void swap(N::T,N::T) {}
}
int main()
{ …Run Code Online (Sandbox Code Playgroud) 根据c ++标准,以下程序是否格式良好或格式不正确?
namespace N { int i; }
using namespace N;
using ::i;
int main() {}
Run Code Online (Sandbox Code Playgroud)
我用不同的编译器得到不同的结果:
根据c ++标准,该程序是否格式良好或格式不正确?需要参考c ++标准.
我正在试图找出应该提交错误的编译器.
c++ using-directives using-declaration language-lawyer name-lookup
我可以创建以下内容:
using Foo = struct { /*Implementation*/ };
template<class>
using Bar = Foo;
Run Code Online (Sandbox Code Playgroud)
但是,以下内容是不允许的:
template<class>
using Bar = struct { /*Implementation*/ };
Run Code Online (Sandbox Code Playgroud)
来自Clang的错误比GCC更有用,并指出:
错误:无法在类型别名模板中定义“(在file:line:column处的匿名结构)”
为何不允许使用第二个代码示例?
注意:
请说明第二个代码示例(如果允许)可能导致语言问题的所有示例。
该标准的任何引用也有帮助。
很抱歉这个愚蠢的问题,但有没有办法将using指令限制在当前文件中,以便它们不会传播到#include这个文件的文件?
在进行提交之前,我希望在我的C#解决方案中运行所有数百项单元测试,因为它们仅需花费几分钟即可运行。但是,如果我已经全部运行了,一切都很好,然后我决定using在我的解决方案中组织指令,是否真的有必要重新运行单元测试?我有一个宏,它遍历解决方案中的所有文件,并在每个宏上运行Visual Studio的“删除和排序”命令。以我的理解,只要using更改指令后仍在构建所有项目,则运行时也应该没问题。这是正确的想法吗?
此外use strict,use还有哪些其他指令?
我原来的类结构类似于:
//def.h
namespace A
{
struct X {};
}
Run Code Online (Sandbox Code Playgroud)
并在需要时转发声明:
//file that needs forward declarations
namespace A { struct X; }
Run Code Online (Sandbox Code Playgroud)
经过一些重构后,X被移动到不同的命名空间,但是为了保持旧代码"工作" using指令的使用:
//def.h
namespace B
{
struct X {};
}
namespace A
{
using ::B::X;
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以访问保持旧语法的同一个类A::X,但前向声明会导致错误.第二个问题是我得到的错误消息并未指向前向声明的位置,并且查找/替换前向声明非常耗时.
现在我解决了问题(困难的方法).
处理这种情况的最佳方法是什么?
IMO,using根本不应该存在,并且所有使用的代码都X应该被重构以容纳新的命名空间(这是一个解决方案),但不幸的是,这不是一个选项.
实际代码要复杂得多,这是一个简化的例子.
c++ refactoring namespaces using-directives forward-declaration
考虑这个库头:
#include<vector>
#include<algorithm>
#include<iostream>
namespace Lib {
namespace detail {
using namespace std;
template<class T>
void sort_impl(istream &in,ostream &out) {
vector<T> v;
{
int n;
in >> n;
v.resize(n);
}
for(auto &i : v) cin >> i;
sort(v.begin(),v.end());
for(auto i : v) out << i << endl;
}
}
inline void sort_std() {
detail::sort_impl<int>(std::cin,std::cout);
}
}
Run Code Online (Sandbox Code Playgroud)
detail命名空间是否成功地将库的客户端(以及库的其余部分实现)与此示例中的using-directive隔离开来?我对于为什么"使用命名空间std"被认为是不良做法的讨论不感兴趣?即使某些论据甚至适用于"包含良好"的使用指令.
请注意,有两个关于相同情况但存在使用声明的问题:
这可以与它们中的任何一个组合,但编辑将是严重的.
using-directives ×10
c++ ×6
namespaces ×5
c# ×3
.net ×1
c++11 ×1
compile-time ×1
javascript ×1
name-lookup ×1
refactoring ×1
strict ×1
templates ×1
unit-testing ×1
use-strict ×1