Created on 2019-06-19.00:00:00 last changed 21 months ago
CWG 2022-11-10
There are related problems in this area; CWG is seeking input to form a holistic view.
Consider the following example:
template<class T>struct Y { typedef typename T::value_type blah; // #1 void swap(Y<T> &); }; template<class T> void swap(Y<T>& Left, Y<T>& Right) noexcept(noexcept(Left.swap(Right))) { } template <class T> struct Z { void swap(Z<T> &); }; template<class T> void swap(Z<T>& Left, Z<T>& Right) noexcept(noexcept(Left.swap(Right))) { } Z<int> x00, y00; constexpr bool b00 = noexcept(x00.swap(y00)); template void swap<int>(Z<int>&, Z<int>&) noexcept(b00); // #2
The question here is whether the explicit instantiation of
swap<int>(Z<int>&, Z<int>&)
at #2 instantiates the exception specification of
swap<int>(Y<int>&, Y<int>&)
which would instantiate Y<int>, resulting in an error on the declaration of
typedef typename T::value_type blah;
at #1.
According to 13.9.2 [temp.inst] paragraph 14,
The noexcept-specifier of a function template specialization is not instantiated along with the function declaration; it is instantiated when needed (14.5 [except.spec]).
According to 14.5 [except.spec] bullet 13.3, one of the reasons an exception specification is needed is:
the exception specification is compared to that of another declaration (e.g., an explicit specialization or an overriding virtual function);
Such a comparison is presumably needed when determining which function template the explicit instantiation is referring to, making the program ill-formed. However, there is implementation variance on this point.
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-02-10 06:31:35 | admin | set | status: review -> open |
2022-11-11 15:36:39 | admin | set | messages: + msg7021 |
2022-11-11 15:36:39 | admin | set | status: open -> review |
2019-06-19 00:00:00 | admin | create |