C dynamic_cast转发声明的类模板编译,但它是安全的吗?

前端之家收集整理的这篇文章主要介绍了C dynamic_cast转发声明的类模板编译,但它是安全的吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下代码编译并给出结果(GCC和clang): @H_403_2@template <typename T> struct Derived; struct Base { template <typename T> void foo(T * const t) { dynamic_cast<Derived<T> * const>(this)->bar(t); } }; template <typename T> struct Derived : Base { void bar(T const *) const { } };

代码将派生到Base中的foo到foo的调用.

作为参考,以下代码不编译:

@H_403_2@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 { } };

GCC提供以下诊断:

@H_403_2@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; ^

C14标准在“一体化规则”一节中规定如下:

5 Exactly one definition of a class is required in a translation unit
if the class is used in a way that requires the class type to be
complete.
[ Example: the following complete translation unit is
well-formed,even though it never defines X:
struct X; // declare X as a struct type
struct X* x1; // use X in pointer formation
X* x2; // use X in pointer formation
—end example ]
[ Note: The rules for
declarations and expressions describe in which contexts complete class
types are required. A class type T must be complete if:
(5.1) — an object of type T is defined (3.1),or
(5.2) — a non-static class data member of type T is declared (9.2),or
(5.3) — T is used as the object type or array element type in a new-expression (5.3.4),or
(5.4) — an lvalue-to-rvalue conversion is applied to a glvalue referring to an object of type T (4.1),or
(5.5) — an expression is converted (either implicitly or explicitly) to type T (Clause 4,5.2.3,5.2.7,5.2.9,5.4),or
(5.6) — an expression that is not a null pointer constant,and has type other than cv void*,is converted to the type pointer to T or reference to T using a standard conversion (Clause 4),a dynamic_cast (5.2.7) or a static_cast (5.2.9),or …

这似乎表明第一个例子是不合法的.这是建构不良的吗?如果是这样,为什么我没有得到错误

解决方法

编辑:经过一点思考:模板首先得到定义,如果你实例化它们.所以你的第一个代码的工作原理找到原因,如果编译器已经达到了实例化模板类的行,首先定义模板.
原文链接:https://www.f2er.com/c/115873.html

猜你在找的C&C++相关文章