简体   繁体   English

用于模板方法的前向声明

[英]Forward Declaration using for a template method

Why do I get an error when using a template method with a forward declared class?为什么在使用带有前向声明 class 的模板方法时会出现错误? I don't actually need a definition of this class, only a declaration.我实际上不需要这个 class 的定义,只需要一个声明。 Or maybe I have misunderstood how it actually works?或者也许我误解了它的实际工作原理? Do I really need to include a corresponding.h file of class B ?我真的需要包含 class B的相应.h 文件吗?

Edited: And why then does forward declaration of class SomeInterface work with static_assert if I actually include "Bh"?编辑:如果我实际上包含“Bh”,为什么 class SomeInterface 的前向声明与static_assert一起工作?

I want to achieve forward declaration to use template method without including ".h" files我想实现前向声明以使用模板方法而不包含“.h”文件

Question after Kevin reply:凯文回复后的问题:

bar() method is actually needed for a Template Method Pattern, so there will be like a family of namespace Second. bar() 方法实际上是模板方法模式所需要的,因此会有类似命名空间的系列 Second。 The problem is if I include more ".h" files from namespace Second, doesn't it be less optimized?问题是,如果我从命名空间第二个中包含更多“.h”文件,它的优化程度是否会降低? This bar() method will be executed only once at start of the program此 bar() 方法只会在程序开始时执行一次

Example code:示例代码:

// 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;
    };
}

If I add this to the A.cpp then it will work fine如果我将其添加到 A.cpp 中,它将正常工作

#include "B.h"

Why do I get an error when using a template method with a forward declared class?为什么在使用带有前向声明 class 的模板方法时会出现错误?

This is not generally a problem.通常不是问题。

I don't actually need a definition of this class, only a declaration.我实际上不需要这个 class 的定义,只需要一个声明。 Or maybe I have misunderstood how it actually works?或者也许我误解了它的实际工作原理?

There is no general rule that template parameters need to be complete types, but there are specific cases, and yours is one of them.没有模板参数必须是完整类型的一般规则,但有特定的情况,你的就是其中之一。

Do I really need to include a corresponding.h file of class B?我真的需要包含一个对应的 class B 的.h 文件吗?

In this case, yes.在这种情况下,是的。

And why then does forward declaration work with static_assert?为什么前向声明与 static_assert 一起工作?

I'm not sure what you mean.我不确定你是什么意思。 The only static_assert in your code is in template method First::A::foo() .代码中唯一的static_assert位于模板方法First::A::foo()中。 You get an error related to that static_assert (though not an assertion failure) when you instantiate the template with a certain template parameter.当您使用某个模板参数实例化模板时,您会收到与该static_assert相关的错误(尽管不是断言失败)。 In what sense, then, do you think the behavior of the static_assert is inconsistent?那么,在什么意义上,您认为static_assert的行为不一致?

The basic problem here is that the std::is_base_of template requires its second type argument to be a complete type.这里的基本问题是std::is_base_of模板要求它的第二个类型参数是一个完整的类型。 This is in its specifications.这在其规格中。 A class type that is (only) forward-declared, with no definition in scope, is not complete. class 类型(仅)向前声明,在 scope 中没有定义,是不完整的。 Therefore, you get an error when you instantiate First::A::foo<Second::B> at a point where no definition of Second::B is in scope. That error is recognized before the assertion can be evaluated, so the static_assert doesn't factor in except as the context of the error.因此,当您在 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