This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 112c. See for the official list.


1483. Non-dependent static_assert-declarations

Section: 13.8  [temp.res]     Status: NAD     Submitter: Mike Miller     Date: 2012-03-23

Recently a customer sent us code of the form,

  template<typename T> void f();
  template<> void f<int>() { }
  template<typename T> void f() {
    static_assert(false, "f() instantiated with non-int type.");

The intent, obviously, was to do compile-time diagnosis of specializations of the template that were not supported, and code of this form is supported by at least some implementations. However, the current wording of 13.8 [temp.res] paragraph 8, appears to invalidate this approach:

If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.

In this example, the static_assert will fail for every generated specialization of f(), so an implementation can issue the error, regardless of whether f() is ever instantiated with a non-int type or not.

A relatively straightforward but somewhat ugly workaround is to define a template like

  template<typename> struct always_false {
    static const bool val = false;

and replace the use of false in the static_assert with always_false<T>::val, making the static_assert dependent.

Considering the fact that a non-dependent static_assert-declaration in a template is otherwise pretty useless, however, it might be worth considering whether to support this usage somehow, especially in light of the fact that it is supported by some implementations, perhaps by treating static_assert-declarations as always dependent, even if the condition is not otherwise dependent.

Rationale (October, 2012):

Although this usage is supported by some implementations and used in some libraries, CWG felt that =delete is the appropriate mechanism for making a function template or member function of a class template unavailable for specialization.