在需要 noexcept-specification 但未实例化的情况下的依赖名称查找示例
Example for dependent name lookup in case when noexcept-specification is needed but not instantiated
来自 cppreference:
When the noexcept-specification of a function template specialization is needed, but hasn't yet been instantiated, the dependent names are looked up and any templates used in the expression are instantiated as if for the declaration of the specialization.
有人可以提供一些这方面的例子吗?
可以在此处查找哪些名称(是否一定涉及 ADL,或者仅仅是必须自己查找的简单依赖类型名称)?
我很难理解上面的意思。
它基本上意味着当noexcept-specification needed(这是一个特定的术语)时,它被实例化。当它被实例化时,它的实例化方式与函数模板声明的实例化方式相同——包括为此必须发生的一切。
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))
当需要 g
的 noexcept-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<T>
只会在需要 noexcept-specification 时实例化,而不是之前。所以 decltype(f<int>(0))
不会尝试实例化 X<int>
,但是 decltype(f<int>())
将是一个硬错误,因为 X<int>
是一个不完整的类型,所以 X<int>::value
是错误的。
来自 cppreference:
When the noexcept-specification of a function template specialization is needed, but hasn't yet been instantiated, the dependent names are looked up and any templates used in the expression are instantiated as if for the declaration of the specialization.
有人可以提供一些这方面的例子吗?
可以在此处查找哪些名称(是否一定涉及 ADL,或者仅仅是必须自己查找的简单依赖类型名称)?
我很难理解上面的意思。
它基本上意味着当noexcept-specification needed(这是一个特定的术语)时,它被实例化。当它被实例化时,它的实例化方式与函数模板声明的实例化方式相同——包括为此必须发生的一切。
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))
当需要 g
的 noexcept-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<T>
只会在需要 noexcept-specification 时实例化,而不是之前。所以 decltype(f<int>(0))
不会尝试实例化 X<int>
,但是 decltype(f<int>())
将是一个硬错误,因为 X<int>
是一个不完整的类型,所以 X<int>::value
是错误的。