c++ - 在我自己的命名空间中定义后缀 _t 数据类型

标签 c++

类型的后缀 _t 由 POSIX 保留,但是如果我在自己的命名空间中使用 _t 后缀定义自己的类型怎么办?

最佳答案

我同意 user6366161answer,其中说“C 对 namespace 一无所知”。 POSIX 主要是一个 C 标准,它定义的 header 供 C 使用(目前是 C99,因为 POSIX 的最后一次主要更新是在 2008 年,远早于 C 2011 标准发布)。因此,当您将 POSIX header 包含到 C++ 程序中时,很可能所有引入的名称都在全局命名空间中 — 除非实现做了一些意想不到的事情。

论文

如果您将自己的类型名称放入您自己的命名空间中,并且您在命名空间中小心引用您的类型和 POSIX 类型,那么就不会与全局命名空间中的 POSIX 类型发生直接冲突。

评论

它有效并不代表它是个好主意。故意与众所周知的 POSIX 类型发生名称冲突是个坏主意,但该技术可以保护您免受意外冲突(以及与 POSIX 保留命名空间中未记录的类型的冲突)。

如果您不顾反对的建议而决定使用这种技术,则需要小心——您会导致代码的临时读者感到困惑。请注意,当您的命名空间中的代码使用您的类型而没有任何范围限定符时,它会在非限定名称发生冲突时使用您的类型而不是 POSIX 类型。您可以使用全局作用域运算符来选取与命名空间中的名称冲突的 POSIX 类型名称。

说明性代码

这是一个例子。计算毫无意义 — 目标是使用 pid_t 类型(POSIX 的整数类型)和位于单独命名空间中的替代类型 pid_t ( NonPosix) 并且是 long double 的别名。

#include <cmath>
#include <unistd.h>

namespace NonPosix
{
    typedef long double pid_t;
    pid_t gruesome(pid_t pos);
    void unsightly();
}

#include <iostream>

using NonPosix::gruesome;
namespace { void obnoxious(); }

int main()
{
    pid_t pid = getpid();
    NonPosix::pid_t angle = gruesome(2.0304815L);

    std::cout << "PID = " << pid << "; angle = " << angle << "\n";

    obnoxious();
    NonPosix::unsightly();

    return 0;
}

// The using statement is invalid - pid_t is already defined in the global scope
#ifdef TRY_USING_NONPOSIX_PID_T
using NonPosix::pid_t;
#endif

namespace {

void obnoxious()
{
    pid_t pid = getppid() + 0.71;   // This is an integral type!
    std::cout << "Obnoxious:\n";
    std::cout << "PID = " << pid << "; angle = " << gruesome(pid) << "\n";
}

}

namespace NonPosix
{

pid_t gruesome(pid_t pos)
{
    pid_t apos = pos + 2.22;
    pid_t rval = atan2l(pos, apos);
    std::cout << "Gruesome: POS = " << pos << "; APOS = " << apos
              << "; RVAL = " << rval << "\n";
    return rval;
}

void unsightly()
{
    pid_t pid = getpid() + 0.65;
    std::cout << "Unsightly:\n";
    std::cout << "PID = " << pid << "; angle = " << gruesome(pid);
    ::pid_t ppid = getppid() + 0.29;    // This is an integral type
    std::cout << "; PPID = " << ppid << "\n";
}

}

该代码是演示代码,不是生产代码,但我认为它说明了一些要点。

示例输出

Gruesome: POS = 2.03048; APOS = 4.25048; RVAL = 0.445654
PID = 7765; angle = 0.445654
Obnoxious:
Gruesome: POS = 670; APOS = 672.22; RVAL = 0.783744
PID = 670; angle = 0.783744
Unsightly:
Gruesome: POS = 7765.65; APOS = 7767.87; RVAL = 0.785255
PID = 7765.65; angle = 0.785255; PPID = 670

最值得注意的是,它说明了我的基本论点:

  • 在带有 _t 后缀的用户定义命名空间中定义的类型不会与 POSIX 类型直接冲突,因为 POSIX 类型位于全局命名空间中。
  • 当名称与基本 POSIX 类型(如 pid_t)冲突时,使用此类类型不是一个好主意。

关于c++ - 在我自己的命名空间中定义后缀 _t 数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37369400/

相关文章:

c++ - xilinx芯片有多常用?

c++ - 使 Thread 本地队列带有计数器

c++ - std::collat​​e::transform 导致段错误

c++ - 在 float 组上使用 mpf_set_ui 停止输出 (GMP c++)

c++ - 多态二元函数

c++ - stringstream 和 double 的精度问题

c++ - 没有匹配的函数调用

c++ - 2个小错误,我无法用C++理解!

c++ - 基类和派生类构造函数的内存分配

c++ - 将匿名对象作为参数传递时,不会调用任何构造函数