using ::std::...;
VS
using std::...;
Есть ли разница (-ы)? Если да, то какой (ы)?
Я видел это:
using ::std::nullptr_t;
что заставило меня задуматься.
using ::std::...;
VS
using std::...;
Есть ли разница (-ы)? Если да, то какой (ы)?
Я видел это:
using ::std::nullptr_t;
что заставило меня задуматься.
В вашем случае, скорее всего, нет разницы. Однако, как правило, разница заключается в следующем:
using A::foo;
разрешает A
из текущей области, а using ::A::foo
выполняет поиск A
из корневого пространства имен. Например:
namespace A
{
namespace B
{
class C;
}
}
namespace B
{
class C;
}
namespace A
{
using B::C; // resolves to A::B::C
using ::B::C; // resolves to B::C
// (note that one of those using declarations has to be
// commented for making this valid code!)
}
Если вы находитесь внутри другого пространства имен, у которого есть собственное вложенное пространство имен std
, тогда ::std
и std
отличаются. Простой пример:
#include <iostream>
namespace A {
namespace std {
void foo() { ::std::cout << "foo" << ::std::endl;}
}
//using std::cout; // compile error
using ::std::cout; //ok
using std::foo; // ok
//using ::std::foo; // compile error
}
Хотя определенно не очень хорошая практика когда-либо иметь вложенное пространство имен std
.
От: http://en.cppreference.com/w/cpp/language/using_declaration
Использование-объявления вводит член другого пространства имен в текущее пространство имен или область видимости
Поэтому, если ваша текущая область уже имеет класс с тем же именем, будет неопределенность между тем, который вы ввели, и тем, который находится в вашем текущем пространстве имен/блоке.
Использование объявления - это просто подмножество директивы using. Директивы использования определяются следующим образом (http://en.cppreference.com/w/cpp/language/namespace):
С точки зрения неквалифицированного поиска имени любого имени после используя-директиву и до конца области, в которой он появляется, каждое имя из имени пространства имен отображается так, как если бы оно было объявлено в ближайшего охватывающего пространства имен, которое содержит как using-directive и namespace-name.
Таким образом, вы можете рассмотреть эти два примера, которые отображают проблемы, которые могут возникнуть.
Он предотвращает неоднозначность между пространствами имен, которые имеют одно и то же имя (пример 1), а также неоднозначность между именами классов в разных пространствах имен (пример 2).
namespace A
{
namespace B
{
struct my_struct {};
}
}
namespace B
{
struct my_struct {};
}
using namespace A; // removing this line makes B:: resolve to the global B::
int main()
{
::B::my_struct; // from global, will not pick A::B::
B::my_struct; // error: 'B' is ambiguous, there is A::B:: and B::
}
Рассмотрим этот пример, который демонстрирует, почему люди избегают использования using namespace std;
using namespace std;
template <typename T>
class vector
{ };
int main()
{
vector<int> v; // which one did you want? ambiguous
::vector<int> v_global; // global one
::std::vector<int> v_std; // std::vector<T>
}
Это зависит от того, где вы используете объявление using
. В глобальной области пространства имен не будет никакой разницы. Однако, если у вас есть код типа
#include <iostream>
#include <vector>
namespace my_namespace {
namespace std {
class vector {
};
}
using std::vector;
}
int main()
{
my_namespace::vector<int> v;
}
он не будет компилироваться, если вы не сообщите компилятору о поиске в глобальном пространстве имен → std namespace → vector в объявлении, указав using ::std::vector
.