使用继承名称空间

时间:2016-04-11 10:14:44

标签: c++ templates

我终于设法将我的单片模板库编译失败归结为一个简单的测试用例。 MSVC不同意Clang和GCC关于代码格式错误的信息,主要是由于名称查找。不幸的是,我不擅长阅读C ++规范,在兼容性时我倾向于相信Clang和GCC,但是你能帮我找到规范的相关部分,以便我可以提交错误吗?

namespace A
{
    template <int _I, int _II>
    struct X {};
}

namespace B
{
    template <int _J>
    struct X {};

    // Clang: OK
    // GCC: OK
    // MSVC: OK
    template <int _K>
    struct Y
    {
        Y(const A::X<_K, _K>&,
          const X<_K>&) {}
    };

    // Clang: OK
    // GCC: OK
    // MSVC: ERROR
    template <int _K>
    struct Z : A::X<_K, _K>
    {
        Z(const A::X<_K, _K>&,
          const X<_K>&) {}
    };

    // Clang: ERROR
    // GCC: ERROR
    // MSVC: ERROR
    struct Q : A::X<1, 1>
    {
        Q(const A::X<1, 1>&,
          const X<1>&) {}
    };
}

int main()
{
    A::X<1, 1> ax;
    B::X<1> bx;

    B::Z<1> bz(ax, bx);

    return 0;
}

有三种情况:

  1. Y并不是特别的。它与两个编译器编译良好。
  2. 编译错误源于Z的CTOR的第二个参数,X没有足够的模板参数。由名称查找来决定我引用哪个X.据我所知,从阅读cppreference开始,当涉及到非限定名称查找时,继承自类不应将其名称引入范围。
  3. 如果Q类本身不是模板,则所有编译器都拒绝它。现在这是我彻底失势的部分。如果课程是模板,为什么重要?
  4. 这里发生了什么?

1 个答案:

答案 0 :(得分:0)

gcc的错误消息提供了线索:

38 : error: wrong number of template arguments (1, should be 2)
const X<1>&) {}
^
4 : note: provided for 'template<int _I, int _II> struct A::X'
struct X {};
^
  

这里发生了什么?

模板类不是代码。它是创建代码的秘诀。当您使用Z<>时,两阶段查找将处理X<i>的定义(此时最好有Q可用)。

X<i>是一个具体的类,因此不涉及两阶段查找。此时必须存在{{1}} - 而且它没有。

一如既往,clang和gcc是正确的。 MSVC不合格。