C++ C++;动态_转换到前向声明的类模板编译,但安全吗?

C++ C++;动态_转换到前向声明的类模板编译,但安全吗?,c++,templates,forward-declaration,incomplete-type,C++,Templates,Forward Declaration,Incomplete Type,以下代码按照(GCC和clang)中的预期编译并给出结果: GCC提供以下诊断功能: main.cpp: In member function 'void Base2::foo(T*)': main.cpp:126:45: error: invalid use of incomplete type 'struct Derived2' dynamic_cast<Derived2 * const>(this)->bar(t);

以下代码按照(GCC和clang)中的预期编译并给出结果:

GCC提供以下诊断功能:

main.cpp: In member function 'void Base2::foo(T*)':
main.cpp:126:45: error: invalid use of incomplete type 'struct Derived2'
         dynamic_cast<Derived2 * const>(this)->bar(t);
                                             ^
main.cpp:119:8: note: forward declaration of 'struct Derived2'
 struct Derived2;
        ^
main.cpp:在成员函数“void Base2::foo(T*)”中:
main.cpp:126:45:错误:不完整类型“struct Derived2”的使用无效
动态铸造(本)->棒材(t);
^
main.cpp:119:8:注:“struct Derived2”的转发声明
结构衍生2;
^
C++14标准在“一个定义”规则部分中规定了以下内容:

5在翻译单元中,一个类只需要一个定义 如果类的使用方式要求类类型为 完成
[示例:以下完整的翻译单元为 格式良好,即使它从未定义X:
struct X;//将X声明为结构类型
结构X*x1;//在指针形式中使用X
X*x2;//在指针形式中使用X
-结束示例]
[注:本规则适用于: 声明和表达式描述完成类的上下文 类型是必需的。在以下情况下,类类型T必须是完整的: (5.1)-定义了类型为T的对象(3.1),或
(5.2)-声明类型为T的非静态类数据成员(9.2),或
(5.3)-T在新表达式(5.3.4)中用作对象类型或数组元素类型,或
(5.4)-将左值到右值的转换应用于引用类型为T(4.1)的对象的glvalue,或
(5.5)-表达式(隐式或显式)转换为T类型(第4条、第5.2.3条、第5.2.7条、第5.2.9条、第5.4条),或
(5.6)-使用标准转换(第4条)、动态转换(5.2.7)或静态转换(5.2.9)或


这似乎表明第一个示例是不合法的。这是构造格式错误?如果是,为什么我没有收到错误?

编辑:经过一点思考:如果实例化模板,则首先定义模板。因此,您的第一个代码可以找到,因为如果编译器已到达实例化的行,则首先定义模板对于依赖名的模板类.< /p>,在实例化的时候测量完整性。对于DyrimeSCAST强制工作,需要多态性,即至少一个虚函数。然后,由于您甚至不检查结果,所以更喜欢使用参考表,其中C++在异常上抛出异常。这听起来像是一个经典示例。当然,做您想做的事情的更惯用的方法是CRTP。@MarkLakata,我熟悉CRTP。在这种情况下,我不能使用它,因为基类实际上是一个访问者库,它的类型需要被前向引用。
struct Derived2;

struct Base2
{
    template <typename T>
    void foo(T * const t)
    {
        dynamic_cast<Derived2 * const>(this)->bar(t);
    }
};

struct Derived2 : Base2
{
    template <typename T>
    void bar(T const *) const { }
};
main.cpp: In member function 'void Base2::foo(T*)':
main.cpp:126:45: error: invalid use of incomplete type 'struct Derived2'
         dynamic_cast<Derived2 * const>(this)->bar(t);
                                             ^
main.cpp:119:8: note: forward declaration of 'struct Derived2'
 struct Derived2;
        ^