Lig*_*ica 60 c++ std language-lawyer c++11
采取以下标准段落:
[C++11: 5.3.3/6]:结果sizeof和sizeof...是类型的常量std::size_t.[注意:std::size_t在标准标题<cstddef>(18.2)中定义. - 尾注]
现在:
[C++11: 18.2/6]:该类型size_t是一个实现定义的无符号整数类型,其大小足以包含任何对象的字节大小.
当然,该段落并不要求这size_t是一个定义的类型别名typedef,但由于它明确声明可以通过标准标题提供<cstddef>,我认为我们可以认为如果没有包含它<cstddef>应该删除任何size_t可用的保证.一个程序.
但是,根据第一个引用,我们可以无论如何获得类型的表达式std::size_t.
int main()
{
typedef decltype(sizeof(0)) my_size_t;
my_size_t x = 0; // OK
std::size_t y = 1; // error: 'size_t' is not a member of 'std'
}
Run Code Online (Sandbox Code Playgroud)
std::size_t该程序不可见,但sizeof(0)仍然给我们一个?真?
因此,说它5.3.3/6是有缺陷的,并且它实际上具有"与std::size_t解决的任何类型相同的类型",而不是 std::size_t它本身,这是不正确的吗?
当然,如果std::size_t是类型别名,这两个是同一个,但同样,这实际上是必需的.
Die*_*ühl 52
标准只是强制要求sizeof(expr)类型与std::size_t.没有任何使用sizeof(expr)使得名称std::size_t可用的任务,因为std::size_t只是命名其中一个内置的整数类型,没有真正的问题.
Yak*_*ont 47
不要混淆地图的地图.
类型可以通过类型名称来命名.这些类型名称可以是内置的,也可以是用户定义的类型,或者它们甚至可以是template参数,并根据实例化引用多种不同的类型.
但名字不是类型.显然,标准并不要求所有类型都有名称 - 经典struct {}是没有名称的类型.
std::size_t是一个类型名称.它命名sizeof(expression)返回的类型.
编译器可以具有该类型的规范名称 - __size_t这将是它具有唯一内置规范类型名称的一种方式.
该条款中的标准保证无论何种类型sizeof(expression),一旦您#include <cstddef>,该名称std::size_t现在指的是该类型.
在标准中,它们按名称引用类型.他们没有说"此类型名称所指的类型",而只是说"$ NAME $类型".编译器可以决定它int是否是另一个名称,__int_32_fast标准也没有异议.
同样的事情发生在std::nullptr_tand std::initializer_list<Ts>和std::type_info:使用这些类型的变量并不总是要求为您提供这些类型的名称的标题包含在您的程序中.
传统的C/C++内置类型都具有不需要标题的规范名称.缺点是这会破坏现有代码,因为全局范围中的新类型名称会与其他标识符冲突.
通过使用"无名类型",您可以通过包含头文件来获取它们的名称,我们可以避免这个问题.
据我了解,此标准段落需要以下表达式:
typeid(sizeof(0)) == typeid(std::size_t)
Run Code Online (Sandbox Code Playgroud)
永远都会屈服true.如果使用实际标识符std::size_t,::size_t或者任何其他别名/ typedef将无关紧要,只要std::typeinfo::operator==()保留该类型的标识即可.
相同类型的身份问题出现在该语言的其他位置.例如,在我的64位机器中,由于函数重新定义,以下代码无法编译:
#include <cstddef>
void foo(std::size_t x)
{}
void foo(unsigned long x)
{}
Run Code Online (Sandbox Code Playgroud)
是.
产生的类型sizeof是一些无符号整数类型; 实现定义了它是哪一个.
例如,在某些特定实现中,sizeof表达式的类型可能是unsigned long.
std::size_t如果它是a typedef,只不过是另一个名字unsigned long.所以这两个陈述:
类型
sizeof ...是类型的常量unsigned long
和
类型
sizeof ...是类型的常量std::size_t
对于该实现正在说完全相同的事情.类型unsigned long和类型std::size_t是相同的类型.不同之处在于后者对于所有(符合标准)实现都是准确的,其中std::size_t可能是别名,例如,unsigned int或其他一些无符号类型.
就编译器而言,sizeof产生类型的结果unsigned long; 编译器(与运行时库相对)不需要任何名称知识size_t.
这一切都假设std::size_t(或者只是size_t你在谈论C)是一个typedef.这在C或C++标准中都没有说明.然而,通过制作size_ttypedef ,实现可以直接符合标准的要求.我不相信有任何其他便携方式来满足这些要求.(它不能是宏或实现定义的关键字,因为这会侵犯用户的名称空间,并且宏不会在std命名空间中作用域.)编译器可以创建size_t一些特定于实现的构造而不是typedef ,但由于typedef运行得非常好,所以没有必要这样做.如果标准声明size_t是typedef ,那将是很好的,恕我直言.
(一个不相关的旁边:真正的问题是标准将结果称为"常量".在ISO C中,"常量"是一个标记,例如整数文字.C++,据我所知,不是'定义名词"常量",但它确实引用了术语的ISO C定义.sizeof ...是一个常量表达式 ;它不是常量.调用结果"常量值"是合理的.)
| 归档时间: |
|
| 查看次数: |
3173 次 |
| 最近记录: |