当前位置: 首页 > 知识库问答 >
问题:

叮当和 gcc 之间的行为差异,当试图通过使用带有虚拟参数的模板别名来隐藏基类来混淆它们时

司空宣
2023-03-14

请考虑以下 c 程序:

class A
{
    protected:
        int x;
};

template<typename X>
using B = A;

template<typename T>
class C : public B<T>
{
    public:
        void f()
        {
            x = 0;
        }
};

int main()
{
}

当使用< code >-STD = c 17-pedantic-errors 作为编译选项用clang和gcc编译时,它们的行为不同:Clang编译时没有任何错误,但是gcc给出一个关于无法查找标识符< code>x的编译错误。

在这种情况下,c标准说了什么?是否允许这两种行为,或者在这种情况下,其中一个编译器是否存在错误?

编译器资源管理器链接:https://godbolt.org/z/EYvYrr

共有2个答案

卢黎昕
2023-03-14

对于C 17,GCC在这里是正确的。

9类型依赖于

>

  • 一个模板参数,

    [...]

    一个简单的模板id,其中模板名称是模板参数,或者任何模板参数是依赖类型,或者是依赖类型或依赖值的表达式,或者是包扩展[ 注意:这包括一个没有模板参数列表的类模板的注入类名。 — 尾注 ] , 或

  • 史承福
    2023-03-14

    这看起来类似于CWG1390,并且看起来Clang的行为与关于应该如何处理这种别名模板的CWG协议一致(在模板定义时急切地替换):

    1390.别名模板专门化的依赖性

    根据17.7.2.1 [临时类型]第8段,如果一个类型是

    • 一个简单的模板id,其中模板名称是模板参数或任何模板参数是依赖类型或依赖类型或值的表达式

    这适用于别名模板特化,即使生成的类型不依赖于模板参数:

       struct B { typedef int type; };
       template<typename> using foo = B;
       template<typename T> void f() {
         foo<T>::type * x;  //error: typename required
       }
    

    对此类案件的规则进行更改是否有正当理由?

    2012年10月会议记录:

    CWG同意在这种情况下不需要< code>typename。在某些方面,别名模板专门化类似于当前的实例化,可以在模板定义时知道。

     类似资料:
    • 我偶然发现了以下代码。案例在MSVC上产生的结果与在叮当声或gcc上产生的结果不同。也就是说,叮当声 13 和 gcc 11.2 调用 的复制构造函数,而 MSVC v19.29 调用模板化构造函数。我使用的是C 17。 考虑到所有编译器都同意调用模板化构造函数的非派生情况(我认为这是clang和gcc中的一个错误,MSVC是正确的吗?还是我解释错了,叮当/gcc是正确的?任何人都可以对可能发生的

    • 本文向大家介绍数字和模拟系统之间的差异。,包括了数字和模拟系统之间的差异。的使用技巧和注意事项,需要的朋友参考一下 数字和模拟系统均用于将信号从一个地方传输到另一个地方,例如音频/视频。数字系统使用二进制格式(0和1),而模拟系统使用幅度变化的电子脉冲发送数据。 以下是数字系统和模拟系统之间的一些重要区别。 。 序号 键 数字系统 模拟系统 1个 信号类型 模拟系统使用大小变化的连续信号。 2 波

    • 数据分发四步走 1.下载模板 ● 下载带员工信息的模板 可下载模板直接使用,也可下载后自己修改 模板中userID匹配钉钉上对应的员工,匹配错误数据会发错 总计之后的列名可以随意修改 2.上传数据 ● 下载带员工信息的模板 注意:IE浏览器无法弹出文件浏览框,可切换其他浏览器 3.检查数据 ● 上传前数据检查,避免问题 实际结果展示,如有问题,会有错误提示 4.发送数据 ● 手机端效果核对 自定义

    • 我拥有的数据格式如下: 我想要在最终表中的数据: 不知道怎么做这个。

    • 很好的一天! 我读得越多,就越感到困惑。外观和别名之间有什么区别? 我有这个类: /应用程序/库/项目/数据。php 和相应的外观,所以我可以只使用PJD进行访问::。 根据周围的一些网页: ... Laravel Facades是代理。它们环绕并调用代码底层真实实现上的函数。此外,在Laravel应用程序的上下文中,通过将这些Facades分配给别名来访问它们。依赖注入容器的这种使用允许您通过简

    • 另一个有用的可能示例:(伪代码)