用于模板方法的前向声明
Forward Declaration using for a template method
为什么在使用带有前向声明 class 的模板方法时会出现错误?我实际上不需要这个 class 的定义,只需要一个声明。或者也许我误解了它的实际工作原理?我真的需要包含 class B
的相应 .h 文件吗?
已编辑:
如果我实际上包含“B.h”,为什么 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"
Why do I get an error when using a template method with a forward declared class?
这不是一般问题。
I don't actually need a definition of this class, only a declaration. Or maybe I have misunderstood how it actually works?
没有模板参数必须是完整类型的一般规则,但是有特定的情况,你的就是其中之一。
Do I really need to include a corresponding .h file of class B?
在这种情况下,是的。
And why then does forward declaration work with static_assert?
我不太清楚你的意思。您的代码中唯一的 static_assert
是在模板方法 First::A::foo()
中。当您使用某个模板参数实例化模板时,您会收到与 static_assert
相关的错误(尽管不是断言失败)。那么,在什么意义上,您认为 static_assert
的行为不一致?
这里的基本问题是 std::is_base_of
模板要求它的第二个类型参数是一个完整的类型。这在其规格中。 class 类型(仅)forward-declared,在范围内没有定义,是不完整的。因此,当您在 Second::B
的定义不在范围内的位置实例化 First::A::foo<Second::B>
时,您会收到错误消息。在可以评估断言之前识别该错误,因此 static_assert
不会考虑 except 作为错误的上下文。
为什么在使用带有前向声明 class 的模板方法时会出现错误?我实际上不需要这个 class 的定义,只需要一个声明。或者也许我误解了它的实际工作原理?我真的需要包含 class B
的相应 .h 文件吗?
已编辑:
如果我实际上包含“B.h”,为什么 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"
Why do I get an error when using a template method with a forward declared class?
这不是一般问题。
I don't actually need a definition of this class, only a declaration. Or maybe I have misunderstood how it actually works?
没有模板参数必须是完整类型的一般规则,但是有特定的情况,你的就是其中之一。
Do I really need to include a corresponding .h file of class B?
在这种情况下,是的。
And why then does forward declaration work with static_assert?
我不太清楚你的意思。您的代码中唯一的 static_assert
是在模板方法 First::A::foo()
中。当您使用某个模板参数实例化模板时,您会收到与 static_assert
相关的错误(尽管不是断言失败)。那么,在什么意义上,您认为 static_assert
的行为不一致?
这里的基本问题是 std::is_base_of
模板要求它的第二个类型参数是一个完整的类型。这在其规格中。 class 类型(仅)forward-declared,在范围内没有定义,是不完整的。因此,当您在 Second::B
的定义不在范围内的位置实例化 First::A::foo<Second::B>
时,您会收到错误消息。在可以评估断言之前识别该错误,因此 static_assert
不会考虑 except 作为错误的上下文。