Explicit instantiation and exception specifications
14.5 [except.spec]
John Spicer

Created on 2019-06-19.00:00:00 last changed 14 months ago


Date: 2022-11-11.15:36:39

CWG 2022-11-10

There are related problems in this area; CWG is seeking input to form a holistic view.

Date: 2022-11-11.15:36:39

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.

Date User Action Args
2023-02-10 06:31:35adminsetstatus: review -> open
2022-11-11 15:36:39adminsetmessages: + msg7021
2022-11-11 15:36:39adminsetstatus: open -> review
2019-06-19 00:00:00admincreate