is_* traits
for binding operations can't be meaningfully specializedSection: 22.10.15.2 [func.bind.isbind] Status: C++14 Submitter: Sean Hunt Opened: 2010-07-19 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [func.bind.isbind].
View all issues with C++14 status.
Discussion:
22.10.15.2 [func.bind.isbind] says for is_bind_expression
:
Users may specialize this template to indicate that a type should be treated as a subexpression in a
bind
call.
But it also says:
If
T
is a type returned frombind
,is_bind_expression<T>
shall be publicly derived fromintegral_constant<bool, true>
, otherwise fromintegral_constant<bool, false>
.
This means that while the user is free to specialize, any specialization
would have to be false
to avoid violating the second
requirement. A similar problem exists for is_placeholder
.
[ 2010 Batavia (post meeting session) ]
Alisdair recognises this is clearly a bug introduced by some wording he
wrote, the sole purpose of this metafunction is as a customization point
for users to write their own bind
-expression types that participate
in the standard library bind
protocol. The consensus was that this
should be fixed in Madrid, moved to Open.
[2011-05-13 Jonathan Wakely comments and provides proposed wording]
The requirements are that is_bind_expression<T>::value
is true when T
is a type returned from bind
, false for any other type, except when
there's a specialization involving a user-defined type (N.B. 16.4.5.2.1 [namespace.std]
means we don't need to say e.g. is_bind_expression<string>
is false.)
integral_constant<bool, false>
and for implementations
to provide specializations for the unspecified types returned from
bind
. User-defined specializations can do whatever they like, as long
as is_bind_expression::value
is sane. There's no reason to forbid
users from defining is_bind_expression<user_defined_type>::value=false
if that's what they want to do.
Similar reasoning applies to is_placeholder
, but a further issue is
that 22.10.15.2 [func.bind.isbind] contains wording for is_placeholder
but
contains no definition of it and the sub-clause name only refers to
is_bind_expression
. The wording below proposes splitting paragraphs 3
and 4 of 22.10.15.2 [func.bind.isbind] into a new sub-clause covering
is_placeholder
.
If the template specializations added by the proposed wording are too
vague then they could be preceded by "for exposition only" comments
[2011-05-18 Daniel comments and provides some refinements to the P/R]
Both bind
-related type traits should take advantage of the
UnaryTypeTrait requirements. Additionally, the updated wording does not
imply that the implementation provides several specializations. Wording was
used similar to the specification of the uses_allocator
type trait
(which unfortunately is not expressed in terms of BinaryTypeTrait requirements).
[Bloomington, 2011]
Move to Ready
Proposed resolution:
This wording is relative to the FDIS.
Change 22.10.15.2 [func.bind.isbind] to:
namespace std { template<class T> struct is_bind_expression; // see below: integral_constant<bool, see below> { };}-1-
-2-is_bind_expression
can be used to detect function objects generated bybind
.bind
usesis_bind_expression
to detect subexpressions.Users may specialize this template to indicate that a type should be treated as a subexpression in abind
call.IfInstantiations of theT
is a type returned frombind
,is_bind_expression<T>
shall be publicly derived fromintegral_constant<bool, true>
, otherwise fromintegral_constant<bool, false>
is_bind_expression
template shall meet the UnaryTypeTrait requirements ([meta.rqmts]). The implementation shall provide a definition that has a BaseCharacteristic oftrue_type
ifT
is a type returned frombind
, otherwise it shall have a BaseCharacteristic offalse_type
. A program may specialize this template for a user-defined typeT
to have a BaseCharacteristic oftrue_type
to indicate thatT
should be treated as a subexpression in abind
call..-3-is_placeholder
can be used to detect the standard placeholders_1
,_2
, and so on.bind
usesis_placeholder
to detect placeholders. Users may specialize this template to indicate a placeholder type.-4- IfT
is the type ofstd::placeholders::_J
,is_placeholder<T>
shall be publicly derived fromintegral_constant<int, J>
, otherwise fromintegral_constant<int, 0>
.
Insert a new sub-clause immediately following sub-clause 22.10.15.2 [func.bind.isbind], the suggested sub-clause tag is [func.bind.isplace]:
is_placeholder
[func.bind.isplace]namespace std { template<class T> struct is_placeholder; // see below }-?-
-?- Instantiations of theis_placeholder
can be used to detect the standard placeholders_1
,_2
, and so on.bind
usesis_placeholder
to detect placeholders.is_placeholder
template shall meet the UnaryTypeTrait requirements ([meta.rqmts]). The implementation shall provide a definition that has a BaseCharacteristic ofintegral_constant<int, J>
ifT
is the type ofstd::placeholders::_J
, otherwise it shall have a BaseCharacteristic ofintegral_constant<int, 0>
. A program may specialize this template for a user-defined typeT
to have a BaseCharacteristic ofintegral_constant<int, N>
withN > 0
to indicate thatT
should be treated as a placeholder type.