类型的后缀 _t
由 POSIX 保留,但是如果我在自己的命名空间中使用 _t
后缀定义自己的类型怎么办?
最佳答案
我同意 user6366161 的 answer,其中说“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/