Title
SFINAE vs undeduced placeholder type
Status
open
Section
9.2.9.6 [dcl.spec.auto]
Submitter
Mike Miller

Created on 2019-05-03.00:00:00 last changed 23 months ago

Messages

Date: 2019-05-03.00:00:00

The status of the following example is not clear:

  template <typename T> auto foo(T);  // Not defined

  template <typename T> struct FooCallable {
    template<class U>
    static constexpr bool check_foo_callable(...) { return false; }

    template<class U, class = decltype(foo(U{})) >
    static constexpr bool check_foo_callable(int) { return true; }

    static constexpr bool value = check_foo_callable<T>(0);
  };
  static_assert(FooCallable<int>::value == false, "");

The static_assert causes the evaluation of the default template argument decltype(foo<int>(int{})). However, foo is not defined, leaving it with an undeduced placeholder return type. This situation could conceivably be handled in two different ways. According to 9.2.9.6 [dcl.spec.auto] paragraph 9,

If the name of an entity with an undeduced placeholder type appears in an expression, the program is ill-formed.

This would thus appear to be an invalid expression resulting from substitution in the immediate context of the declaration and thus a substitution failure.

The other alternative would be to treat the presence of an undeduced placeholder type for a function template as satisfying the requirements of 13.9.2 [temp.inst] paragraph 4,

Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist or if the existence of the definition affects the semantics of the program.

and attempt to instantiate foo<int>. That instantiation fails because the definition is not provided, which would then be an error outside the immediate context of the declaration and thus a hard error instead of substitution failure.

There is implementation divergence on the handling of this example.

History
Date User Action Args
2019-05-03 00:00:00admincreate