在这种情况下,C++ 标准是否保证模板实例化点?
Does c++ standard guarantee point of template instantiation in this case?
template< typename _Type >
struct TypeChecker {};
template< typename _Type >
bool f0( _Type obj )
{
return TypeChecker< _Type >::value;
}
struct S {};
void f1()
{
f0( S{} );
}
template<>
struct TypeChecker< S > : std::true_type {};
显然 "TypeChecker< S > : std::true_type" 在定义 f1() 时是未知的,但是 MSVC2019 和 Clang 都可以毫无错误地编译它。
我不确定这是否是标准保证的行为。
我在SO中发现了几个类似的问题:
When is a C++ template instantiation type checked?
Incomplete class usage in template
Can the point-of-instantiation be delayed until the end of the translation unit?
我相信这是规范中的相关部分:
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.
但是 "the end of the translation unit is also considered a point of instantiation" 到底是什么意思?
这是否意味着它依赖于实现?就像 "compiler A" 编译上面的代码没有错误而 "compiler B" 没有,而两者都符合标准?
或者此代码是否保证任何标准 c++ 编译器的格式正确?
您的程序是 ill-formed, no diagnostic required,因为显式特化没有在它被(或将被)隐式实例化的(第一个)位置之前定义。实例化点业务有点像转移注意力:它管理名称查找,而不是有效性(除了它也是格式错误的 NDR 以使该查找的结果取决于选择了多个实例化点中的哪一个)。
template< typename _Type >
struct TypeChecker {};
template< typename _Type >
bool f0( _Type obj )
{
return TypeChecker< _Type >::value;
}
struct S {};
void f1()
{
f0( S{} );
}
template<>
struct TypeChecker< S > : std::true_type {};
显然 "TypeChecker< S > : std::true_type" 在定义 f1() 时是未知的,但是 MSVC2019 和 Clang 都可以毫无错误地编译它。
我不确定这是否是标准保证的行为。
我在SO中发现了几个类似的问题: When is a C++ template instantiation type checked? Incomplete class usage in template Can the point-of-instantiation be delayed until the end of the translation unit?
我相信这是规范中的相关部分:
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.
但是 "the end of the translation unit is also considered a point of instantiation" 到底是什么意思? 这是否意味着它依赖于实现?就像 "compiler A" 编译上面的代码没有错误而 "compiler B" 没有,而两者都符合标准?
或者此代码是否保证任何标准 c++ 编译器的格式正确?
您的程序是 ill-formed, no diagnostic required,因为显式特化没有在它被(或将被)隐式实例化的(第一个)位置之前定义。实例化点业务有点像转移注意力:它管理名称查找,而不是有效性(除了它也是格式错误的 NDR 以使该查找的结果取决于选择了多个实例化点中的哪一个)。