用于模板方法的前向声明



为什么使用前向声明类的模板方法时会出现错误?实际上我不需要这个类的定义,只需要一个声明。或者是我误解了它的工作原理?我真的需要包含B类的对应。h文件吗?

编辑:那么为什么类SomeInterface的前向声明与static_assert工作,如果我实际上包括"B.h"?

我想实现使用模板方法的前向声明,而不包含".h"文件

Kevin回复后的问题:

bar()方法实际上是模板方法模式所需要的,所以会有类似于命名空间家族的第二种方法。问题是如果我加了更多的"。h"第二,它不是更不优化吗?这个bar()方法将只在程序开始时执行一次

示例代码:

// A.cpp
#include "A.h"
namespace Second
{
    class SomeInterface;
    class B;
}
namespace First
{
    class A
    {
    public:
        A() = default;
        template <typename M>
        void foo()
        {
            static_assert(std::is_base_of<Second::SomeInterface, M>::value, "You need to use SomeInterface or Derived from it");
        }
        void bar() // -- Template Method Pattern
        {
            foo<Second::B>(); // -- C2139   'Second::B': an undefined class is not allowed as
                      // an argument to compiler intrinsic type trait '__is_base_of'
            foo<Second::C>();
            foo<Second::D>();
            //...
        }
    };
}
// B.cpp
#include "B.h"
#include "SomeInerface.h"
namespace Second
{
    class B : public SomeInterface
    {
    public:
        B() = default;
    };
}

如果我把它添加到a.p,它就会正常工作了

#include "B.h"

为什么使用前向声明类的模板方法时会出现错误?

一般来说不是问题。

我实际上不需要这个类的定义,只需要一个声明。或者是我误解了它的工作原理?

没有一般规则要求模板形参必须是完整类型,但在某些特殊情况下,你的形参就是其中之一。

我真的需要包含B类的相应。h文件吗?

在这种情况下,可以。

那么为什么前向声明与static_assert一起工作呢?

我不太明白你的意思。代码中唯一的static_assert是在模板方法First::A::foo()中。当您使用某个模板参数实例化模板时,您会得到一个与该static_assert相关的错误(尽管不是断言失败)。那么,在什么意义上,你认为static_assert的行为是不一致的?这里的基本问题是std::is_base_of模板要求它的第二个类型参数是一个完整的类型。这是它的规格说明。(仅)前向声明的类类型,在作用域中没有定义,是不完整的。因此,当您在范围内没有Second::B定义的地方实例化First::A::foo<Second::B>时,您会得到一个错误。该错误在对断言进行求值之前就被识别出来了,因此static_assert除了作为错误的上下文之外,不考虑其他因素。

相关内容

  • 没有找到相关文章

最新更新