Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For non-member functions, a type such as <code>typedef void(Function)()</code> has several uses, but for member functions the only application is to declare a variable which holds a function pointer. Hence, other than a stylistic preference, there's no strict need to allow this syntax and it has been omitted from the standard.</p> <h3>Background</h3> <p>The <code>::</code> is a scope resolution operator, and the syntax <code>X::Y</code> is reserved for <code>static</code> member access if <code>X</code> is a class type. So <code>X::*Z</code> was another syntax invented to define <em>pointer-to-member</em>.</p> <p>Forget <em>member-function</em> for a while, just think about <em>member-data</em>, and see this code:</p> <pre><code>struct X { int a; }; int X::*pa = &amp;X::a; //pointer-to-member X x = {100}; //a = 100 cout &lt;&lt; (x.*pa) &lt;&lt; endl; </code></pre> <p>It defines a <em>pointer-to-member-data</em>, and the <code>cout</code> uses it to print the value of <code>a</code> of object <code>x</code>, and it prints:</p> <pre><code>100 </code></pre> <p>Demo : <a href="http://www.ideone.com/De2H1" rel="nofollow">http://www.ideone.com/De2H1</a></p> <p>Now think, if <code>X::pa</code> (as opposed to <code>X::*pa</code>) were allowed to do that, then you've written the above as:</p> <pre><code>int X::pa = X::a; //not &amp;X::a </code></pre> <p>Seeing this syntax, how would you tell if <code>X::a</code> is a <code>static</code> member or non-static member? That is one reason why the Standard came up with <em>pointer-to-member</em> syntax, and uniformly applies it to <em>non-static member-data</em> as well as <em>non-static member-function</em>.</p> <p>In fact, you <strong>cannot</strong> write <code>X::a</code>, you've to write <code>&amp;X::a</code>. The syntax <code>X::a</code> would result in compilation error (see <a href="http://www.ideone.com/FfGao" rel="nofollow">this</a>).</p> <hr> <p>Now extend this argument of <em>member-data</em> to <em>member-function</em>. Suppose you've a typedef defined as:</p> <pre><code>typedef void fun(); </code></pre> <p>then what do you think the following code does?</p> <pre><code>struct X { fun a; }; </code></pre> <p>Well, it defines member <code>a</code> of type <code>fun</code> (which is function taking no argument, and returning void), and is equivalent to this:</p> <pre><code>struct X { void a(); }; </code></pre> <p>Surprised? Read on.</p> <pre><code>struct X { fun a; //equivalent to this: void a(); }; void X::a() //yes, you can do this! { cout &lt;&lt; "haha" &lt;&lt; endl; } </code></pre> <p>We can use exactly the same syntax to refer to <code>a</code> which is now a member-function:</p> <pre><code>X x; x.a(); //normal function call void (X::*pa)() = &amp;X::a; //pointer-to-member (x.*pa)(); //using pointer-to-member </code></pre> <p>The similarity is the synatax on the right hand side : <code>&amp;X::a</code>. Whether <code>a</code> refers to a member-function or member-data, the syntax is same.</p> <p>Demo : <a href="http://www.ideone.com/Y80Mf" rel="nofollow">http://www.ideone.com/Y80Mf</a></p> <p><strong>Conclusion:</strong></p> <p>As we know that we cannot write <code>X::a</code> on the RHS, no matter if <code>a</code> is a member-data or member-function. The only syntax which is allowed is <code>&amp;X::f</code> which makes it necessary that the target type (on LHS) must be <em>pointer</em> as well, which in turn makes the syntax <code>void (X::*pa)()</code> absolutely necessary and fundamental, as it fits in with other syntax in the language.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload