1059. Usage of no longer existing FunctionType concept

Section: 23.14.13.2 [func.wrap.func] Status: NAD Concepts Submitter: Daniel Krügler Opened: 2009-03-13 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [func.wrap.func].

View all issues with NAD Concepts status.

Discussion:

Due to a deliberate core language decision, the earlier called "foundation" concept std::FunctionType had been removed in N2773 shortly before the first "conceptualized" version of the WP (N2798) had been prepared. This caused a break of the library, which already used this concept in the adapted definition of std::function (23.14 [function.objects]/2, header <functional> synopsis and 23.14.13.2 [func.wrap.func]).

A simple fix would be to either (a) make std::function's primary template unconstrained or to (b) add constraints based on existing (support) concepts. A more advanced fix would (c) introduce a new library concept.

The big disadvantage of (a) is, that users can define templates which cause compiler errors during instantiation time because of under-constrainedness and would thus violate the basic advantage of constrained code.

For (b), the ideal constraints for std::function's template parameter would be one which excludes everything else but the single provided partial specialization that matches every "free function" type (i.e. any function type w/o cv-qualifier-seq and w/o ref-qualifier). Expressing such a type as as single requirement would be written as

template<typename T>
requires ReferentType<T> // Eliminate cv void and function types with cv-qual-seq
                         //   or ref-qual (depending on core issue #749)
      && PointeeType<T>  // Eliminate reference types
      && !ObjectType<T>  // Eliminate object types

Just for completeness approach (c), which would make sense, if the library has more reasons to constrain for free function types:

auto concept FreeFunctionType<typename T>
  : ReferentType<T>, PointeeType<T>, MemberPointeeType<T>
{
  requires !ObjectType<T>;
}

I mention that approach because I expect that free function types belong to the most natural type categories for every days coders. Potential candidates in the library are addressof and class template packaged_task.

[ Batavia (2009-05): ]

Alisdair would prefer to have a core-supported FunctionType concept in order that any future changes be automatically correct without need for a library solution to catch up; he points to type traits as a precedent. Further, he believes that a published concept can't in the future be changed.

Bill feels this category of entity would change sufficiently slowly that he would be willing to take the risk.

Of the discussed solutions, we tend toward option (c). We like the idea of having a complete taxonomy of native types, and perhaps erred in trimming the set.

We would like to have this issue reviewed by Core and would like their feedback. Move to Open.

Proposed resolution:

  1. Change in 23.14 [function.objects]/2, Header <functional> synopsis:

    // 20.6.16 polymorphic function wrappers:
    class bad_function_call;
    template<FunctionTypeReferentType F>
    requires PointeeType<F> && !ObjectType<F>
    class function; // undefined
    
  2. Change in 23.14.13.2 [func.wrap.func]:

    namespace std {
    template<FunctionTypeReferentType F>
    requires PointeeType<F> && !ObjectType<F>
    class function; // undefined