【问题标题】:Explicit Type Conversion and Multiple Simple Type Specifiers显式类型转换和多个简单类型说明符
【发布时间】:2010-01-27 01:40:20
【问题描述】:

要对T 类型的对象进行值初始化,可以执行以下操作之一:

T x = T();
T x((T()));

我的问题涉及由简单类型说明符组合指定的类型,例如unsigned int

unsigned int x = unsigned int();
unsigned int x((unsigned int()));

Visual C++ 2008 和 Intel C++ Compiler 11.1 接受这两个版本而不发出警告; Comeau 4.3.10.1b2 和 g++ 3.4.5(诚然,不是最近的)没有。

根据C++标准(C++03 5.2.3/2,expr.type.conv):

表达式T(),其中T 是非数组完整对象类型或(可能是cv 限定的)void 类型的简单类型说明符(7.1.5.2),创建一个右值指定类型,值初始化

7.1.5.2 说,“简单类型说明符是”,然后是一个包含unsignedint 的列表。

因此,鉴于在 5.2.3/2 中,“simple-type-specifier”是单数,而unsignedint 是两个类型说明符,那么上面使用unsigned int 的示例是否无效? (如果是,那么后续的问题是,微软和英特尔支持上述表达方式是否不正确?)

这个问题更多是出于好奇;对于由多个简单类型说明符组合指定的所有类型,值初始化等效于零初始化。 (这个问题是comments in response to this answer to a question about initialization提示的)。

【问题讨论】:

  • 你怎么敢质疑我。 :3 我认为表达式(unsigned int) 命名了一个类型。
  • @GMan: (unsigned int)() 使用 gcc 3 和 4 以及 VC8 失败。 typedefed 版本当然可以。
  • H​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​米。 :(​​​​​​​​​

标签: c++ value-initialization


【解决方案1】:

posted this question to comp.lang.c++.moderated.

C++ 标准委员会的 Daniel Krügler 同意 unsigned int 是一个简单类型说明符的组合,并且它本身不是一个简单类型说明符的解释。

关于表 7 referenced by Jerry Coffin 的标题,Krügler 说:

我同意表 7 的表头(这是表 9 中最 最近的 N3000 草案)有点误导,但之前的 [dcl.type.simple]/2 中的文本在我看来非常清晰,当它说:

表 7 总结了简单类型说明符的有效组合 以及它们指定的类型。”

(抱歉,我花了这么长时间才从新闻组发回这里;我完全忘记了)

【讨论】:

    【解决方案2】:

    在第 7.1.5.2 节中,继续阅读表 7,其中包含允许作为简单说明符的完整列表(其中包括“unsigned int”)。

    【讨论】:

    • 我会说该表并非旨在定义“简单类型说明符”的概念。此外,表后的措辞提到了“多个简单类型说明符”。这是允许我们交替使用unsigned intint unsigned 的措辞,这可能意味着unsigned int 实际上是多个 简单类型说明符。
    • @AndreyT:这也是我的解释。我也认为表格列的标题“说明符”暗示了很多。
    • 嗯...在我的标准副本中,表格的标题是“简单类型说明符及其指定的类型”。有了这个标题,相信表格中的某些东西不是一个简单的类型说明符似乎是一个可怕的延伸。
    • 我不认为该标题排除了“说明符”列包含简单类型说明符组合的解释,特别是根据 §7.1.5.2/1 中的语法描述和§7.1.5/1 中的列表。不过,我以前错了。 (在一个完全不相关的注释中,有没有一种简单的方法可以将 § 字符放入答案和 cmets 中?)
    • @James McNelis:我不认为它完全排除了解释,但我确实认为它让它变得有些牵强。输入 §: 在 Windows 下,按 Alt,然后使用数字键盘输入带前导零 (0167) 的十进制代码。在 Linux 下,您在输入十六进制值 (A7) 时按住 Alt 和 Ctrl 键。如果你经常这样做,X 支持 ~/.Xmodmap 文件,Windows 有一个键盘布局创建器。对于其他系统,您可能需要进行一些谷歌搜索...
    【解决方案3】:

    嗯,有时你需要一个 typedef。如果它没有说需要诊断,那么他们支持这一点并没有错。不过,为了可移植性,您可以使用 typedef(uint16_tuint64_t,尽管这些可能不正确),或者使用模板引用类型名:

    iterator<void, unsigned long>::value_type( 5 )
    

    不合理的冗长怎么样?

    编辑:呃,或者干脆5ul。这使得 unsigned shortunsigned charsigned char 成为您无法轻松显式构造的唯一类型。

    【讨论】:

    • 我宁愿有:template &lt;typename T&gt; struct same_type{ typedef T type; };,简单一点。
    • 我宁愿两者都没有 ;v) 。我只是想在 STL 中考虑一些东西。恒等模板和恒等函子的遗漏总是让我感到困惑。
    • 您在正确性问题上是对的。 “符合标准的实现可能有扩展......只要它们不会改变任何格式良好的程序的行为”(1.4/8,intro.compliance);我完全忘记了有关语言语法、扩展和合规性的规则。
    • A std::identity 出现在最新的 C++0x 草案中(参见 n3000, 20.3.3/1)。
    • 让我们赞美std::identity: stackoverflow.com/questions/75538/hidden-features-of-c/… :) 它有很多不错的用例:)
    【解决方案4】:

    7.1.5.2:

    简单类型说明符指定先前声明的用户定义类型或基本类型之一`

    这意味着unsigned int i = unsigned int() 是合法的,因为unsigned int 是一个基本类型(因此是一个简单类型说明符,参见3.9.1)。

    同样适用于以下类型:

    long double
    long long
    long long int
    unsigned long
    unsigned long long int
    short int
    ...
    

    【讨论】:

    • 我认为这里有一个逻辑谬误:您的论点是,“如果 T 是一个简单的类型说明符,那么 T 要么是先前定义的用户定义类型,要么 T 是基本类型之一。 T 是基本类型,因此 T 是简单类型说明符”(您正在确认结果)。
    • @James:我不明白你在说什么,你的问题表明T t = T() 对于简单类型说明符是合法的,我的引述说基本类型是简单类型说明符,所以@ 987654325@是合法的。
    • 我很抱歉;今天早上我发布的时候,我显然还没有喝足够的咖啡。我不同意您的解释,即如果 T 是基本类型,则 T 也必须是简单类型说明符。我相信 T 实际上可能是多个简单类型说明符(例如,unsigned int 是一个基本类型,但由两个简单类型说明符 unsignedint 指定)。我认为有很多声明可以支持这一点,例如3.9.1,注释 40:“关于类型和指定它们的类型说明符的 序列 之间的对应关系,请参见 7.1.5.2”(强调我的)
    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多