【问题标题】:Does c++ standard guarantee point of template instantiation in this case?在这种情况下,C++ 标准是否保证模板实例化点?
【发布时间】:2020-06-19 21:53:04
【问题描述】:
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 : 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”编译上面的代码没有错误而“编译器B”没有,而两者都符合标准?

或者任何标准 c++ 编译器都保证这段代码格式正确?

【问题讨论】:

    标签: c++ templates language-lawyer


    【解决方案1】:

    你的程序是ill-formed, no diagnostic required,因为显式特化没有在它被(或将被)隐式实例化的(第一个)位置之前定义。实例化业务的重点是一条红鲱鱼:它控制名称查找,而不是有效性(除了查找结果取决于选择多个实例化点中的哪一个也是不正确的 NDR)。

    【讨论】:

    • 感谢您的回答,这是否意味着 MSVC 和 clang 在这件事上都不符合标准?
    • @visor24:不,不是这个意思。 IFNDR 表示对于此代码的实现没有没有要求,因此任何行为(包括做你想做的事)都是正确的。
    猜你喜欢
    • 1970-01-01
    • 2015-10-19
    • 2017-01-20
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多