繁体   English   中英

用于模板方法的前向声明

[英]Forward Declaration using for a template method

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

编辑:如果我实际上包含“Bh”,为什么 class SomeInterface 的前向声明与static_assert一起工作?

我想实现前向声明以使用模板方法而不包含“.h”文件

凯文回复后的问题:

bar() 方法实际上是模板方法模式所需要的,因此会有类似命名空间的系列 Second。 问题是,如果我从命名空间第二个中包含更多“.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.cpp 中,它将正常工作

#include "B.h"

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

通常不是问题。

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

没有模板参数必须是完整类型的一般规则,但有特定的情况,你的就是其中之一。

我真的需要包含一个对应的 class B 的.h 文件吗?

在这种情况下,是的。

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

我不确定你是什么意思。 代码中唯一的static_assert位于模板方法First::A::foo()中。 当您使用某个模板参数实例化模板时,您会收到与该static_assert相关的错误(尽管不是断言失败)。 那么,在什么意义上,您认为static_assert的行为不一致?

这里的基本问题是std::is_base_of模板要求它的第二个类型参数是一个完整的类型。 这在其规格中。 class 类型(仅)向前声明,在 scope 中没有定义,是不完整的。 因此,当您在 scope 中没有定义Second::B的位置实例化First::A::foo<Second::B>时,会出现错误。在评估断言之前会识别出该错误,因此static_assert不考虑 except 作为错误的上下文。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM