【问题标题】:Clang template incomplete typeClang 模板不完整类型
【发布时间】:2017-01-18 07:53:52
【问题描述】:

我有以下代码在 Visual Studio 和 g++ 下编译良好,但在 Clang 中我收到错误“错误:'ns::B' 是不完整的类型”

啊.h

#pragma once
namespace ns
{
    class B;

    class A
    {
        friend class B;
        class Inner
        {
        public:
            int x;
            Inner(int x) : x(x) {}
        };
    public:
        template<typename T>
        T getB(int i)
        {
            B b = B(Inner(i));
            return T(b);
        }

    };
}

B.h

#pragma once
#include "A.h"

namespace ns
{
    class B
    {
        A::Inner i;
    public:
        B(A::Inner i) : i(i)
        {}

        operator int() const
        {
            return i.x;
        }
    };
}

main.cpp

#include "A.h"
#include "B.h"

int main()
{
    ns::A a;
    return a.getB<int>(5);
}

据我了解,代码应该可以工作,因为当模板被实例化时,B 已经完成。它是否正确?如果是这样,有没有办法在 Clang 中解决这个问题?

【问题讨论】:

  • 不相关的旁注:main.cpp 中的#include "a.h" 没有意义。
  • @SingerOfTheFall 重复包含标题很好,但它们必须包含此处未显示的保护。
  • @Potatoswatter 是的,对不起,我在复制时确实错过了。

标签: c++ templates clang


【解决方案1】:

程序格式错误,不需要诊断。

[temp.res]/8:

程序格式错误,不需要诊断,如果:

  • [...]
  • 紧随其定义的模板的假设实例化由于不依赖于模板参数的构造而导致格式错误,或者
  • [...]

【讨论】:

  • ... 所以一种解决方案是只在A.h 中前向声明A::getB,并在B.h 中定义它。
  • @Potatoswatter 太棒了,非常感谢。你知道为什么它会在 VS 和 g++ 中工作吗?
  • @MikeJones:Visual 不会对模板进行 2 次通过检查(不符合标准),因此不会检查非依赖代码。对于 g++(它执行 2 次通过检查),他们错过了诊断的机会。
猜你喜欢
  • 2016-04-11
  • 1970-01-01
  • 2011-12-14
  • 2021-12-11
  • 2014-05-11
  • 2019-11-15
  • 2019-06-21
相关资源
最近更新 更多