【问题标题】:Casting pointer as template argument: Comeau & MSVC compile, GCC fails将指针转换为模板参数:Comeau 和 MSVC 编译,GCC 失败
【发布时间】:2009-09-13 15:38:21
【问题描述】:

考虑以下代码:

template<int* a>
class base {};

int main()
{
    base<(int*)0> test;
    return 0;
}

Comeau 和 MSVC 都可以毫无问题地编译它(除了 Comeau 关于未使用变量的警告),而 GCC 在 base&lt;(int*)0&gt; test; 行上失败,说明

在函数“int main()”中: 转换为整数或枚举类型以外的类型不能出现在常量表达式中

模板参数 1 无效

它到底在抱怨什么?谁是对的——这段代码应该编译吗?值得注意的是,我的 GCC 版本非常旧(3.4.2),因此可能与它有关。谢谢。

【问题讨论】:

  • 仅供参考:使用 gcc 4.4.1:test.cpp:6:错误:转换为整数或枚举类型以外的类型不能出现在常量表达式中 test.cpp:6:错误: 模板参数 1 无效 test.cpp:6: 错误: ';' 之前的声明类型无效令牌
  • 感谢 jdehaan,所以我们知道这与我的版本无关。
  • 欢迎您。我尝试稍微修改代码以使其编译。细微的变化并不能说明问题...
  • open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#354 的缺陷报告提供了洞察力。似乎喜剧演员认为该标准在这一点上过于严格并允许它,很清楚它会在稍后(2005年)的标准中得到解决和允许。当然,缺陷记者约翰斯派塞为科莫工作。 xD
  • 很好,感谢链接 litb,这正是我想要做的事情:D

标签: c++ templates gcc compiler-construction


【解决方案1】:

来自draft standard(已添加重点):

14.1.3 非类型模板参数应具有以下之一(选项- 盟友 cv-qualified) 类型: ... --指向对象的指针,接受地址常量表达式设计- 使用外部链接对命名对象进行命名, ...

显然,用空指针实例化模板是不合法的,因为空指针不指向“具有外部链接的命名对象”。

【讨论】:

  • +1!我尝试通过提供一个指向 int 的指针作为参数并出现以下错误(比之前非常神秘的错误)错误:'& a' 不是'int *'类型的有效模板参数,因为'a'没有外部链接
  • 这看起来很有希望,但我认为这不能解释为什么 GCC 和 Comeau 不同。例如,如果我更改为base&lt;(int*)1&gt; Comeau 和 GCC 都无法编译。此外,如果此要求来自“草稿”,那么我的 GCC 无法编译它,但它已经 4 岁了,所以如果在那段时间将它添加到标准中,那么它不会是让 GCC 窒息的那个要求.
  • 人们经常引用草案,因为标准本身不是免费的。然而,最终草案和标准文本之间不应该有任何显着差异。自 2003 年以来没有任何新标准(这是次要更正),因此您的 GCC 版本肯定比该要求更年轻。错误消息听起来也好像编译器确切地知道它在说什么。我很想认为这是正确的。
  • 为了澄清这一点,引用的文本来自 1996 年标准草案。标准('03)有:“-指向对象的指针或指向函数的指针”,在其他地方它说参数应该是“-具有外部链接的对象或函数的地址”。所以严格按照 '03 comeau 是错误的,尽管是故意错误的,而是“符合”尚未发布的 c++0x。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 2019-09-11
  • 2018-12-28
  • 2014-05-16
相关资源
最近更新 更多