【问题标题】:Example for dependent name lookup in case when noexcept-specification is needed but not instantiated在需要 noexcept 规范但未实例化时的依赖名称查找示例
【发布时间】:2023-03-25 01:46:01
【问题描述】:

来自 cppreference:

当需要函数模板特化的 noexcept 规范但尚未实例化时,将查找从属名称并实例化表达式中使用的任何模板,就像声明特化一样。

有人可以提供一些例子吗?

可以在此处查找哪些名称(是否必然涉及 ADL,或者是否只是必须自行查找的普通依赖类型名称)?

我很难理解上面的意思。

【问题讨论】:

    标签: c++ templates c++14 noexcept name-lookup


    【解决方案1】:

    它基本上意味着当noexcept-specification 需要(这是一个特定的术语)时,它被实例化。当它被实例化时,它的实例化方式与函数模板声明的实例化方式相同——包括为此必须发生的一切。

    cppreference 示例有:

    template<class T> T f() noexcept(sizeof(T) < 4);
    decltype(f<void>()) *p; // error
    

    即使我们没有评估 f,它的 noexcept-specification 也是需要(因为 f 是通过重载决议选择的,并且会是 odr - 如果已评估则使用)。所以在那一点上它被实例化了。但该实例化是一个错误,因为 sizeof(void) 格式不正确。

    另一方面,这个稍作修改的版本是可以的:

    template<class T> T f(int);
    template<class T> T f() noexcept(sizeof(T) < 4);
    decltype(f<void>(1)) *p; // ok
    

    我们从不实例化 f() 的 noexcept 规范,因为它不是必需的。

    名称查找没有什么特别之处。这只是正常的模板规则适用,所以:

    struct N {
        struct X { };
        void h(X);
    }
    void h(int) noexcept;
    template<class T> void g(T t) noexcept(noexcept(h(t))
    

    当需要gnoexcept-specification 时,那就是实例化h(t)——它可能会也可能不会像往常一样执行 ADL。 noexcept(g(0)) 将是 true,但 noexcept(g(N::X{})) 将是 false

    此外,任何相关模板仅在需要时才被实例化。所以如果我们有:

    template<class T> struct X;
    template<class T> T f() noexcept(X<T>::value);
    template<class T> T f(int);
    

    X&lt;T&gt; 只会在需要 noexcept-specification 时被实例化,而不是之前。所以decltype(f&lt;int&gt;(0)) 不会尝试实例化X&lt;int&gt;,但decltype(f&lt;int&gt;()) 将是一个硬错误,因为X&lt;int&gt; 是一个不完整的类型,所以X&lt;int&gt;::value 是格式错误的。

    【讨论】:

      猜你喜欢
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多