Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The answer is not clear c++

Tags:

Here is a test question:

Consider the following code:

class A {     typedef int I; // private member     I f();     friend I g(I);     static I x; }; 

Which of the following are valid:

a. A::I A::f() { return 0; } b. A::I g(A::I p = A::x); c. A::I g(A::I p) { return 0; } d. A::I A::x = 0; 

Answer to this question is considered correct only the first version (a.), but why? All them are valid in my opinion. Even tested all they compile successfully. Why only the first answer is correct?

like image 496
Narek Avatar asked Jul 16 '14 01:07

Narek


2 Answers

Whoever wrote the original answer to the test is wrong.

  • This example comes (exactly) from the C++ standard itself, section § 11/7, [class.access], and has been copied by the one who wrote the "test"

The example goes even further in the standard, with templates (I'll omit them here):

      class A {           typedef int I;      // private member           I f();           friend I g(I);           static I x;       };        A::I A::f() { return 0; }       A::I g(A::I p = A::x);       A::I g(A::I p) { return 0; }       A::I A::x = 0; 
  • Quoting the standard for the explanation:

Here, all the uses of A::I are well-formed because A::f and A::x are members of class A and g is a friend of class A. This implies, for example, that access checking on the first use of A::I must be deferred until it is determined that this use of A::I is as the return type of a member of class A. ]

  • It compiles with both gcc and clang
like image 67
quantdev Avatar answered Nov 24 '22 08:11

quantdev


They are all valid C++.

Here is the exact code, it is an example from the standard itself:

http://www.open-std.org/jtc1/sc22/open/n2356/access.html

This is how I parse them:

a. A::I A::f() { return 0; } // defines A::f() which was previously prototyped  b. A::I g(A::I p = A::x);    // declares prototype g(A::I), but doesn't define it  c. A::I g(A::I p) { return 0; } // defines g(A::I)  d. A::I A::x = 0; // defines static storage for A::x which was previously declared in A 

These all compile, both individually, and collectively.

like image 45
codenheim Avatar answered Nov 24 '22 08:11

codenheim