Scope resolution operator and const

前端 未结 4 1185
抹茶落季
抹茶落季 2021-01-24 03:27

Let\'s take the following code:

#include  // std::string    
using namespace std;
int main() {
  //const::int i = 42;       -> Error: \"expected         


        
4条回答
  •  佛祖请我去吃肉
    2021-01-24 04:12

    Your using namespace std; is bit of a red herring. Note that const::std::string str = "Foo"; also compiles. The reason this compiles (and the reason your const::string str = "Foo"; compiles) is because :: is the scope resolution operator. Spacing is irrelevant. Just as there's no difference between a+b+c and a + b + c, there's no difference between const::string str and const :: string str (and similarly, between const::std::string str and const :: std :: string str).

    ::,::std::, and std:: are all examples of a nested-name-specifier, which is described in 5.1.1 ¶8 of c++ n3290 (a draft of the C++11 standard). The const is a keyword and this cannot be interpreted as the leading part of a nested-name-specifier. This means that const::string can only be interpreted as if you had written const ::string.

    In the context of using namespace std; at global namespace level, there's nothing wrong with using ::string because the leading :: means to look up what follows in the global namespace. You've pulled all of namespace std into the global namespace. Thus const::string str declares str as a const-qualified variable of type std::string.

    What about const::int i = 42;? There's no place in the standard for such a construct. Looking at 7.1.6.2 ¶1 (c++n3290), A simple-type-specifier is

    • A type-name, optionally preceded by a nested-name-specifier,
    • A nested-name-specifier template simple-template-id,
    • One of the built-in primitive types,
    • The auto keyword, or
    • A decltype-specifier.

    A type-name is a class-name, an enum-name, a typedef-name, or a simple-template-id. The built-in primitive types do not fall in the category of a type-name. This means that the following will (and does) compile:

    #include  
    #include 
    
    typedef int Int; // Now we can use ::Int because Int is a type-name.
    
    using namespace std;
    int main() {
      const::Int i = 42;         // No error.
      const::string str = "Foo"; // No error.
      cout << i << ' ' << str << '\n';
    }
    

提交回复
热议问题