Using fully qualified name for std namespace in C++

2.2k Views Asked by At

If name in C++ is not fully qualified, e.g. std::cout, it can lead to an unintentional error, such as mentioned at https://en.cppreference.com/w/cpp/language/qualified_lookup. But using a fully qualified name for ::std namespace, e.q. ::std::cout, is very rare, as I have noticed.

Is there any reason why a fully qualified name for ::std namespace is not used?

And what about using fully qualified name for own created namespaces? Is it good idea?

2

There are 2 best solutions below

3
Christophe On BEST ANSWER

You are completely right, in the sense that yyyy::xxx can be ambiguous if there is a namespace yyyy and also a class yyyy which are both visible in the same scope. In this case only the full qualification ::yyyy::xxx can solve the ambiguity. The example of your link makes it very clear:

// from cppreference.com
#include <iostream>
int main() {
  struct std{};
  std::cout << "fail\n"; // Error: unqualified lookup for 'std' finds the struct
  ::std::cout << "ok\n"; // OK: ::std finds the namespace std
}

But in practice, it's difficult to create a conflicting std at top level, since most of the includes from the standard library will make it fail:

#include <iostream>

struct std {      // OUCH: error: ‘struct std’ redeclared as different kind of symbol
    int hello;  
}; 

This means that to create a conflict, you'd need to define local classes or introduce a using clause in another namespace. In addition, nobody will (dare to) call a class std.

Finally, in practice, ::yyyy::xxx is less convenient to read. All this explains why you won't find it very often.

Additional remark

The problem is not so much for std which is well known, but rather for your own namespaces and third party libraries. In this case, the namespace alias would be a better alternative to :::yyyy to disambiguate:

namespace foo {
    void printf() { }
}
int main() {
    foo::printf();          // ok, namespace is chose because no ambiguity
    struct foo {/*...*/ };  // creates ambiguity
    //foo::printf();        // error because struct foo is chosen by name lookup
    ::foo::printf();        // ok, but not if you  decide to move the code to be nested in another namespace
    namespace  mylib = foo ;   // or ::foo (see discussion below)
    mylib::printf();        // full flexibility :-)
}

Its advantage is a higher flexibility. Suppose for example that you'd move your code to nest it in an enclosing namespace. With the namespace alias, your code could continue to work as is (in the worst case with a minor adjustment in the alias definition). With the global scope resolution, you'd have to change all the statements where the global namespace ::foo would be used.

1
Gaurav G On

To maintain big code or better readability or clashes in names, C++ has provided namespace " a declarative region". A namespace definition can appear only at global scope, or nested within another namespace.

#Sample Code
#include <iostream>
int main() 
{
      struct std{};
      std::cout << "fail\n"; // Error: unqualified lookup for 'std' finds the struct
      ::std::cout << "ok\n"; // OK: ::std finds the namespace std
}

In the above code compiler is looking for cout in struct std , but in next line when you use ::std::cout it looks for cout in globally defined std class.

Solution:

#include <iostream>
//using namespace std; // using keyword allows you to import an entire namespace at once. 

namespace test
{
    void cout(std::string str)
    {
       ::std::cout<<str; 
    }
}

int main() 
{
    cout("Hello");//'cout' was not declared in this scope
    ::test::cout("Helloo ") ;
    ::std::cout<<"it is also ok\n";
}

Or use the in this way , it is just for better readability

##
using namespace test;
int main() 
{
    cout("Hello");//'cout' was not declared in this scope
    cout("Helloo ") ;
    ::std::cout<<"it is also ok\n";
}