如果专业化已经被隐式实例化了,它是否被隐式实例化? [英] Is a specialization implicitly instantiated if it has already been implicitly instantiated?
问题描述
标题中的问题很清楚.更具体地说,请考虑以下示例:
The question in the title is clear enough. To be more specific, consider the following example:
#include <type_traits>
template <typename T>
struct is_complete_helper {
template <typename U>
static auto test(U*) -> std::integral_constant<bool, sizeof(U) == sizeof(U)>;
static auto test(...) -> std::false_type;
using type = decltype(test((T*)0));
};
template <typename T>
struct is_complete : is_complete_helper<T>::type {};
// The above is an implementation of is_complete from https://stackoverflow.com/a/21121104/5376789
template<class T> class X;
static_assert(!is_complete<X<char>>::type{});
// X<char> should be implicitly instantiated here, an incomplete type
template<class T> class X {};
static_assert(!is_complete<X<char>>::type{}); // #1
X<char> ch; // #2
此代码使用GCC和Clang编译.
根据 [temp.inst]/1 :
除非已明确实例化或明确指定了类模板专业化,否则当在需要完全定义的对象类型的上下文中引用该专业化时或在类类型的完整性时引用该专业化时,将隐式实例化该类模板专业化影响程序的语义.
由于static_assert(!is_complete<X<char>>::type{})
会隐式实例化
X<char>
,它会生成不完整的类型.
X<char>
is implicitly instantiated due to static_assert(!is_complete<X<char>>::type{})
, which generates an incomplete type.
然后,在定义了X
之后,#1
暗示X<char>
不会再次实例化(仍然不完整),而#2
暗示X<char>
确实会再次实例化(成为完整类型).
Then, after the definition of X
, #1
suggests that X<char>
is not instantiated again (still incomplete) while #2
suggests that X<char>
is indeed instantiated again (becomes a complete type).
如果某个专业化已经被隐式实例化,它是否被隐式实例化?为什么#1
和#2
之间有区别?
Is a specialization implicitly instantiated if it has already been implicitly instantiated? Why is there a difference between #1
and #2
?
欢迎对标准进行解释.
推荐答案
如果某个专业化已经被隐式实例化,那么它是否被隐式实例化?
Is a specialization implicitly instantiated if it has already been implicitly instantiated?
不.根据 [temp.point]/8 :>
类模板的专门化在翻译单元中最多具有一个实例化点.
A specialization for a class template has at most one point of instantiation within a translation unit.
x<char>
仅需要实例化一次,而在第一个静态断言中将其命名时,只需在ch
之前将其实例化即可.但是[temp.point]/8也说
x<char>
need only be instantiated once, and it's not when it's named in the first static assertion, only before ch
. But, [temp.point]/8 also says
功能模板,成员功能模板的专业化, 或类模板的成员函数或静态数据成员的 在翻译单元中具有多个实例化点,并且 除上述实例化点外,对于任何 这样的专业化在内部具有实例化的点 翻译单元,翻译单元的末尾也被认为是 实例化点. [...]如果两个不同的实例化点根据一个定义规则赋予模板专业化不同的含义,则程序格式错误,无需诊断.
A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. [...] If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required.
和is_complete_helper::test
是成员函数模板,其声明在静态断言之前被实例化.因此,它也必须在TU的末尾具有实例化.在哪里可能会给出不同的结果.因此,此特征取决于不良的NDR构造.
And is_complete_helper::test
is a member function template whose declaration is instantiated before the static assertion. So it must also have an instantiation at the end of the TU. Where it will likely give a different result. So this trait is depending on an ill-formed NDR construct.
这篇关于如果专业化已经被隐式实例化了,它是否被隐式实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!