命名空间

命名空间解决了不同代码片段之间的命名冲突问题。

#include <iostream>
#include <string>
#include <vector>

namespace mycode {
    void foo() {std::cout << "调用命名空间 mycode 内的 foo() 函数" << std::endl;}
    void bar() {std::cout << "调用命名空间 mycode 内的 bar() 函数" << std::endl;}

}

int main() {
    {
        // 调用命名空间内的函数
        mycode::foo();
        mycode::bar();
    }

    {
        // 使用 using 指令(directive)
        // 凡是命名空间 mycode 内的函数都可以只写函数名,不用写命名空间前缀
        using namespace mycode;
        foo();
        bar();
    }

    {
        // 使用 using 声明(declaration)
        // 只有命名空间 mycode 内的 foo() 函数可以只写函数名,不用写命名空间前缀
        // 命名空间 mycode 内的其他函数还是要写完整的命名空间前缀
        using mycode::foo;
        foo();
        mycode::bar();
    }

    return 0;
}

嵌套命名空间和命名空间别名

#include <iostream>
#include <string>
#include <vector>

// 嵌套命名空间,写法1,C++17之前
namespace mycode {
    namespace Networking {
        namespace FTP {
            void foo() {std::cout << "调用 foo() 函数" << std::endl;}

        }
    }
}

// 嵌套命名空间,写法2,语法更紧凑
namespace mycode::Networking::FTP {
    void bar() {std::cout << "调用 bar() 函数" << std::endl;}
}


int main() {
    {
        // 调用嵌套命名空间中的函数
        mycode::Networking::FTP::foo();
        mycode::Networking::FTP::bar();
    }

    {
        // 命名空间别名
        namespace MyFTP = mycode::Networking::FTP;
        
        // 二者效果相同,都是调用 foo() 函数:
        mycode::Networking::FTP::foo();  // 调用嵌套命名空间中的 foo() 函数
        MyFTP::foo();  // 用别名调用 foo() 函数
    }

    return 0;
}

内联命名空间

在内联命名空间(inline namespaces)中声明的东西,都会自动地在父级命名空间中可用。

如有命名空间mycode,其有子级内联命名空间Networking,我在Networking中声明的函数foo(),既可以这样调用:mycode::Networking::foo();也可以这样调用:mycode::foo(),就像直接把函数 foo() 声明在了命名空间mycode中一样。

如 std::string 字符串字面量。标准字面量 s 在命名空间 std::literals::string_literals 中定义。命名空间 string_literals 和 literals 是内联命名空间。所以,使用下面的 using 指令中的任意一条后,都可以在代码中使用标准字面量 s

using namespace std;
using namespace std::literals;
using namespace std::string_literals;
using namespace std::literals::string_literals;

std::string 字符串字面量的示例代码如下。来自 C++风格字符串,std:string 类

#include <iostream>
#include <string>
 
int main() {
    {
        // std::string 字符串字面量
        // 标准字面量

        using namespace std::literals::string_literals;  // 内联命名空间
        auto str {"hello world"s};  // str 类型是 std::string
    }
 
    return 0;
}

怎样定义自己的内联命名空间?使用 inline 关键字,代码如下:

#include <iostream>

namespace mycode {
    inline namespace Networking {
        inline namespace FTP {
            void foo() {std::cout << "调用 foo() 函数" << std::endl;}
        }
    }
}

int main() {
    // 由于 Networking 和 FTP 是内联命名空间,
    // 如下 3 种方式都可以调用 foo() 函数
    {
        using namespace mycode::Networking::FTP;
        foo();
    }

    {
        using namespace mycode::Networking;
        foo();
    }

    {
        using namespace mycode;
        foo();
    }

    return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注