Title
Constrained error_code/error_condition members
Status
c++11
Section
[syserr]
Submitter
Daniel Krügler

Created on 2009-10-14.00:00:00 last changed 154 months ago

Messages

Date: 2010-10-21.18:28:33

[ Should this resolution be accepted, I recommend to resolve 1229 as NAD ]

  1. In [syserr.errcode.overview]/1, class error_code, change as indicated:

    // 19.5.2.2 constructors:
    error_code();
    error_code(int val, const error_category& cat);
    template <class ErrorCodeEnum>
      error_code(ErrorCodeEnum e,
        typename enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type * = 0);
    
    // 19.5.2.3 modifiers:
    void assign(int val, const error_category& cat);
    template <class ErrorCodeEnum>
      typename enable_if<is_error_code_enum<ErrorCodeEnum>::value>::typeerror_code&
        operator=(ErrorCodeEnum e);
    void clear();
    
  2. Change [syserr.errcode.constructors] around the prototype before p. 7:

    template <class ErrorCodeEnum>
    error_code(ErrorCodeEnum e,
      typename enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type * = 0);
    

    Remarks: This constructor shall not participate in overload resolution, unless is_error_code_enum<ErrorCodeEnum>::value == true.

  3. Change [syserr.errcode.modifiers] around the prototype before p. 3:

    template <class ErrorCodeEnum>
      typename enable_if<is_error_code_enum<ErrorCodeEnum>::value>::typeerror_code&
        operator=(ErrorCodeEnum e);
    

    Remarks: This operator shall not participate in overload resolution, unless is_error_code_enum<ErrorCodeEnum>::value == true.

  4. In [syserr.errcondition.overview]/1, class error_condition, change as indicated:

    // 19.5.3.2 constructors:
    error_condition();
    error_condition(int val, const error_category& cat);
    template <class ErrorConditionEnum>
      error_condition(ErrorConditionEnum e,
        typename enable_if<is_error_condition_enum<ErrorConditionEnum>::type* = 0);
    
    // 19.5.3.3 modifiers:
    void assign(int val, const error_category& cat);
    template<typenameclass ErrorConditionEnum>
      typename enable_if<is_error_condition_enum<ErrorConditionEnum>, error_code>::typeerror_condition &
        operator=( ErrorConditionEnum e );
    void clear();
    
  5. Change [syserr.errcondition.constructors] around the prototype before p. 7:

    template <class ErrorConditionEnum>
      error_condition(ErrorConditionEnum e,
        typename enable_if<is_error_condition_enum<ErrorConditionEnum>::value>::type* = 0);
    

    Remarks: This constructor shall not participate in overload resolution, unless is_error_condition_enum<ErrorConditionEnum>::value == true.

  6. Change [syserr.errcondition.modifiers] around the prototype before p. 3:

    template <class ErrorConditionEnum>
      typename enable_if<is_error_condition_enum<ErrorConditionEnum>::value>::typeerror_condition&
        operator=(ErrorConditionEnum e);
    

    Remarks: This operator shall not participate in overload resolution, unless is_error_condition_enum<ErrorConditionEnum>::value == true.

    Postcondition: *this == make_error_condition(e).

    Returns: *this

Date: 2010-10-21.18:28:33

[ 2009-10 Santa Cruz: ]

Moved to Ready.

Date: 2009-10-18.00:00:00

[ 2009-10-18 Beman adds: ]

I support this proposed resolution, and thank Daniel for writing it up.

Date: 2011-05-03.22:13:16

I'm just reflecting on the now SFINAE-constrained constructors and assignment operators of error_code and error_condition:

These are the only library components that are pro-actively announcing that they are using std::enable_if as constraining tool, which has IMO several disadvantages:

  1. With the availability of template default arguments and decltype, using enable_if in the C++0x standard library, seems unnecessary restricting implementation freedom. E.g. there should be no need for a useless specification of a dummy default function argument, which only confuses the reader. A more reasonable implementation could e.g. be

    template <class ErrorCodeEnum
     class = typename enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type>
    error_code(ErrorCodeEnum e);
    

    As currently specified, the function signatures are so unreadable, that errors quite easily happen, see e.g. 1229.

  2. We have a lot of constrained functions in other places, that now have a standard phrase that is easily understandable:

    Remarks: This constructor/function shall participate in overload resolution if and only if X.

    where X describes the condition. Why should these components deviate?

  3. If enable_if would not be explicitly specified, the standard library is much better prepared for the future. It would also be possible, that libraries with partial support for not-yet-standard-concepts could provide a much better diagnostic as is possible with enable_if. This again would allow for experimental concept implementations in the wild, which as a result would make concept standardization a much more natural thing, similar to the way as templates were standardized in C++.

    In summary: I consider it as a library defect that error_code and error_condition explicitly require a dependency to enable_if and do limit implementation freedom and I volunteer to prepare a corresponding resolution.

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2010-10-21 18:28:33adminsetmessages: + msg1267
2010-10-21 18:28:33adminsetmessages: + msg1266
2010-10-21 18:28:33adminsetmessages: + msg1265
2009-10-14 00:00:00admincreate