Section: 22.10.10 [logical.operations] Status: CD1 Submitter: Martin Sebor Opened: 2001-01-06 Last modified: 2016-01-28
Priority: Not Prioritized
View all issues with CD1 status.
Discussion:
The class templates const_mem_fun_t
in 20.5.8, p8 and
const_mem_fun1_t
in 20.5.8, p9 derive from unary_function<T*, S>
, and
binary_function<T*,
A, S>
, respectively. Consequently, their argument_type
, and
first_argument_type
members, respectively, are both defined to be T*
(non-const).
However, their function call member operator takes a const T*
argument. It is my opinion that argument_type
should be const
T*
instead, so that one can easily refer to it in generic code. The
example below derived from existing code fails to compile due to the
discrepancy:
template <class T>
void foo (typename T::argument_type arg) // #1
{
typename T::result_type (T::*pf) (typename
T::argument_type)
const = // #2
&T::operator();
}
struct X { /* ... */ };
int main ()
{
const X x;
foo<std::const_mem_fun_t<void, X>
>(&x);
// #3
}
#1 foo()
takes a plain unqualified X*
as an argument
#2 the type of the pointer is incompatible with the type of the member
function
#3 the address of a constant being passed to a function taking a non-const
X*
Proposed resolution:
Replace the top portion of the definition of the class template const_mem_fun_t in 20.5.8, p8
template <class S, class T> class const_mem_fun_t
: public
unary_function<T*, S> {
with
template <class S, class T> class const_mem_fun_t
: public
unary_function<const T*, S> {
Also replace the top portion of the definition of the class template const_mem_fun1_t in 20.5.8, p9
template <class S, class T, class A> class const_mem_fun1_t
: public
binary_function<T*, A, S> {
with
template <class S, class T, class A> class const_mem_fun1_t
: public
binary_function<const T*, A, S> {
Rationale:
This is simply a contradiction: the argument_type
typedef,
and the argument type itself, are not the same.