Neglected class "special members" - transfer function

A, operator overloading

This keyword is not very usual in fact almost used, but this happens keywords and new / delete the class was withdrawn keywords often appear together, so that the whole situation looks even more strange. Prior should be looking at C ++ stl library seen in the custom class member in the transfer function, it is hoped to make an object can be converted to type bool (usually used in a logical expression if the class). Was converted in to see this function when it is withdrawn and another of stl :: tr1 extension of functional together. As we all know, function is ideal stl everything (even if a different number of parameters) something that can be invoked (functor classes, functions) packaged as a form of external unified function pointer. Since it is a function of the ideal, then it is best able to judge whether he is a null pointer, that can be expressed as bool features.
Note that the use of the following two classes of operator, look the same, relatively easily confused, but they are two completely different syntax / semantic structure, is a conversion function, is an operator function. From the linguistic point of view, the most obvious of which is a grammatical features keyword operator guidance starts, the other type is the beginning of the guide.
4.4.7-gcc \ libstdc ++ - v3 \ the include \ tr1_impl \ Functional
/// class function
Template <_res typename, typename ... _ArgTypes>
class function <_res (_ArgTypes ...)>
: public _Maybe_unary_or_binary_function <_res, _ArgTypes. ..>,
Private _Function_base
{
......
// [3.7.2.3] function capacity

/**
* @brief Determine if the %function wrapper has a target.
*
* @return @c true when this %function object contains a target,
* or @c false when it is empty.
*
* This function will not throw an exception.
*/
operator _Safe_bool() const
{
if (_M_empty())
return 0;
else
return &_Hidden_type::_M_bool;
}

// [3.7.2.4] function invocation

/**
* @brief Invokes the function targeted by @c *this.
* @returns the result of the target.
* @throws bad_function_call when @c !(bool)*this
*
* The function call operator invokes the target function object
* stored by @c this.
*/
_Res operator()(_ArgTypes... __args) const;
……
}

Two, C ++ syntax description of the two structures

In the "C ++ 11-draft-starndard.pdf " , for guiding the second syntax is called "function-operator-ID"
operator-function-ID:
operator OPERATOR
OPERATOR: One of
new new Delete new new [] Delete []
? | - + * /% &
! = <> + == * = / =% =
! = & = | = << >> << >> = = == =
<=> = && || + + - -> * ->
() []
is defined for the syntax conversion-function-id is such a
conversion-function-id:
operator Conversion-type-ID
only these two grammatical structure, they is the operator began, but when parsing, their difference is obvious. From here to understand the concept, operator-function-id and the same as ordinary function names, operator and operators together as an atomic unit of grammar, its meaning and the same as ordinary function names. Intuitively can say: Where can appear ordinary function, the function name is replaced by "operator + operator" are possible.
tsecer @ harry: cat -n operator.function.id.




. 5 return X * X;
. 6}
. 7 int MUL (int X)
. 8 {
. 9 return X * X;
10}
. 11};
12 is
13 is int operator + (const A & A, int X)
14 {
15 return X + X;
16}
the Add int. 17 (A & A const, int X)
18 is {
. 19 return X + X;
20 is}
21 is
22 is A A;
23 is int main ()
24 {
25 return a.operator * (. 1) a.mul + (. 1) + + operator (a,. 1) + the Add (a,. 1);
26 is}
tsecer @ Harry: GCC -C operator.function.id.cpp
tsecer @ Harry:
see above code snippet can be seen, "operator *" and " operator + "as a whole, and add the corresponding mul respectively, which are grammatically equivalent, which are more advanced type of unqualified-id syntax units, their identifiers and literal identifier the same level, but in the lexical describe the different rules
primary-expression:
literal
this
( expression )
id-expression
lambda-expression
id-expression:
unqualified-id
qualified-id
unqualified-id:
identifier
operator-function-id
conversion-function-id
literal-operator-id
~ class-name
~ decltype-specifier
template-id

Three, C ++ explanation for the conversion function

From the organizational point of view directory, conversion is a special member functions and constructor / destructor same in the same directory, but ctor / dtor most commonly used to cover up the conversion, rather than conversion unworthy of the name. They reason his uncle that they are actually not guide the use of type declaration. Constructor example, it is identified by the class name and the same location; destructor is due to the beginning of the '~', and the corresponding conversion is required at the beginning of 'operator' keyword recognition.
12 Special Member Functions 256
12.1 Constructors........................................... . 256
12.2 the Temporary Objects......................................... 258
12.3 Conversions. ............................................ 261
12.4 Destructors... .......................................... 264
12.5 Free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
12.6 Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
12.7 Construction and destruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
12.8 Copying and moving class objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
12.9 Inheriting constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
If a conversion function is a member function, the
“12.3.2 Conversion functions”中对于转换函数的定义
type of the conversion function (8.3.5) is “function taking no parameter returning conversion-type-id”.

Four, gcc special treatment for members of the class

Here only to note that: gcc internal conversion and is indeed the ctor / dtor processed simultaneously, which denotes that the conversion overlooked but not really a base structure / member of a particular class destructor then high frequency of use.
4.4.7-GCC \ GCC \ CP \ parser.c
static cp_declarator *
cp_parser_direct_declarator (cp_parser * Parser,
cp_parser_declarator_kind dcl_kind,
int * ctor_dtor_or_conv_p,
BOOL member_p)
{
......
IF (class_type)
{
IF (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
SFK = sfk_destructor;
the else IF (IDENTIFIER_TYPENAME_P (unqualified_name))
SFK = sfk_conversion;
the else IF (/ * There apos NO Way to DECLARE A constructor
for AN Anonymous type, the even IF The type
GOT A name for Linkage Purposes * /.
TYPE_WAS_ANONYMOUS (class_type! )
&& constructor_name_p (unqualified_name,
class_type))
{
unqualified_name = constructor_name (class_type);
sfk = sfk_constructor;
}

if (ctor_dtor_or_conv_p && sfk != sfk_none)
*ctor_dtor_or_conv_p = -1;
}
……
}

Fifth, use simple example

Note that in this example the function of the fun is an object pointer rather than a conventional
tsecer @ Harry: CAT function.cpp
#include <Tr1 / Functional>

std::tr1::function<void()> fun;

int main()
{
if (!fun)
{
return 123;
}
return 0;
}
tsecer@harry:
tsecer@harry: cat -n function.cpp
1 #include <tr1/functional>
2
3 std::tr1::function<void()> fun;
4
5 int main()
6 {
7 if (!fun)
8 {
9 return 123;
10 }
11 return 0;
12 }
tsecer@harry: g++ -g function.cpp
tsecer@harry: ./a.out
tsecer@harry: echo $?
123
tsecer@harry: gdb ./a.out
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/harry/study/cpp.rvalue/a.out...done.
(gdb) b 7
Breakpoint 1 at 0x400604: file function.cpp, line 7.
(gdb) r
Starting program: /home/harry/study/cpp.rvalue/./a.out

Breakpoint 1, main () at function.cpp:7
7 if (!fun)
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.tl2.3.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc++-4.8.5-4.el7.x86_64
(gdb) si
0x0000000000400609 7 if (!fun)
(gdb)
std::tr1::function<void ()>::operator std::tr1::function<void ()>::_Hidden_type* std::tr1::function<void ()>::_Hidden_type::*() const (this=0x400510 <_start>) at /usr/include/c++/4.8.2/tr1/functional:2048
2048 operator _Safe_bool() const
(gdb) list
2043 */
2044 #if __cplusplus >= 201103L
2045 explicit operator bool() const
2046 { return !_M_empty(); }
2047 #else
2048 operator _Safe_bool() const
2049 {
2050 if (_M_empty())
2051 return 0;
2052 else
(gdb) si
0x000000000040070f 2048 operator _Safe_bool() const
(gdb)
0x0000000000400712 2048 operator _Safe_bool() const
(gdb)
0x0000000000400716 2048 operator _Safe_bool() const
(gdb)
2050 if (_M_empty())
(gdb)
0x000000000040071e 2050 if (_M_empty())
(gdb)
0x0000000000400721 2050 if (_M_empty())
(gdb)
std::tr1::_Function_base::_M_empty (this=0x4007ad <__libc_csu_init+77>) at /usr/include/c++/4.8.2/tr1/functional:1760
1760 bool _M_empty() const { return !_M_manager; }
(gdb) si
0x00000000004006c7 1760 bool _M_empty() const { return !_M_manager; }
(gdb) p _M_manager
$1 = (std::tr1::_Function_base::_Manager_type) 0xc35f415e415d415c
(gdb) s
std::tr1::function<void ()>::operator std::tr1::function<void ()>::_Hidden_type* std::tr1::function<void ()>::_Hidden_type::*() const (this=0x601060 <fun>) at /usr/include/c++/4.8.2/tr1/functional:2051
2051 return 0;
(gdb) list
2046 { return !_M_empty(); }
2047 #else
2048 operator _Safe_bool() const
2049 {
2050 if (_M_empty())
2051 return 0;
2052 else
2053 return &_Hidden_type::_M_bool;
2054 }
2055 #endif
(gdb) si
0x0000000000400731 2051 return 0;
(gdb) p _M_manager
$2 = (std::tr1::_Function_base::_Manager_type) 0x0
(gdb)

Guess you like

Origin www.cnblogs.com/tsecer/p/12558312.html