error_code
/error_condition members
Section: 19.5 [syserr] Status: C++11 Submitter: Daniel Krügler Opened: 2009-10-14 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [syserr].
View all issues with C++11 status.
Discussion:
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:
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.
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?
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.
[ 2009-10-18 Beman adds: ]
I support this proposed resolution, and thank Daniel for writing it up.
[ 2009-10 Santa Cruz: ]
Moved to Ready.
Proposed resolution:
[ Should this resolution be accepted, I recommend to resolve 1229 as NAD ]
In 19.5.4.1 [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();
Change 19.5.4.2 [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
.
Change 19.5.4.3 [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
.
In 19.5.5.1 [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();
Change 19.5.5.2 [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
.
Change 19.5.5.3 [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