data member with the class name - c++

The standard says,
"A member of a class T cannot use T as its name if the member is a static data member, a member function, a member type, a member template, an enumerator of an unscoped enumeration, a member of a member anonymous union. However, a non-static data member may use the name T as long as there are no user-declared constructors."
However if I create this class, it gives an compile error.
class G
{
int G;
};
I am using VS2013. Is it not allowed in Microsoft or ?

If VC++ doesn't allow this, it's a bug.
However, this language "feature" is for the purpose of C compatibility, and Microsoft has decided not to emphasize C. For example, C99 features are unavailable as a rule until adopted by C++. You should never purposely declare such a member in C++.
(It's allowed in C simply by default: there are no restrictions on the naming of members, and all members are nonstatic data members.)

Related

Is there a reason to differentiate between static and non-static data members in terms of prohibition of the usage of abstract types?

In class.abstract we can see in the Note 3 that:
An abstract class can be used only as a base class of some other class; no objects of an abstract class can be created except as subobjects of a class derived from it ([basic.def], [class.mem]).
This rules out the usage of abstract classes as subobjects and it makes sense to me (though this is just a note, which is non-normative, IIRC).
However, in class.mem we can read that:
The type of a non-static data member shall not be an incomplete type ([basic.types]), an abstract class type ([class.abstract]), or a (possibly multi-dimensional) array thereof.
[Note 5: In particular, a class C cannot contain a non-static member of class C, but it can contain a pointer or reference to an object of class C. — end note]
(emphasis mine)
What seems strange to me is the specific wording: "non-static". Why is it explicitly stated that this refers to non-static members? I don't believe we're allowed to have static declarations or definitions of objects of abstract types. Does the standard actually allow static data members to be abstract and no sane compiler implements that? Or it does prohibit such uses (in that case why the distinction in static vs non-static data in the aforementioned paragraph)?
Whether or not a class is abstract is not known until the class is defined.
It has always been allowed to declare a static data member with an incomplete class type, as long as the type is complete by the time the static data member is defined. Since the type of a static data member may be incomplete on its declaration, it also follows that it might be an abstract class that the compiler doesn't yet know is abstract. For this reason, it is appropriate to defer checking of the abstractness until the static data member's definition. At the time of definition, if the type of the static data member is found to be an abstract class, then the compiler should issue a diagnostic. This was the reasoning in P0929, which added the current wording in C++20.
With non-static data members, their types are required to be complete at the time of declaration, and the declaration of the non-static data member serves as a definition. So the abstractness must be checked at that point.
Why is it explicitly stated that this refers to non-static members?
Because that allows declaration of static members with incomplete type. Here is a minimal example that is allowed, but wouldn't be allowed if "non-static" wasn't explicitly stated in that rule:
struct S {
// array of unknown bound is an incomplete type
static int arr[];
//int arr2[]; // is not allowed because of the rule
};
int S::arr[3]; // definition of the static member
Does the standard actually allow static data members to be abstract
No, that would contradict the rule quoted by Vlad unless there was a more specific rule overriding it (and there isn't to my knowledge). Specifying the rule to non-static seems to be relevant to incomplete types only; and not to abstract types. As such, listing "abstract type" in the rule explicitly seems redundant and thus confusing (but not contradictory) to me Edit: Brian's answer clarifies why it makes sense.
In the first quote there is an answer to your question
An abstract class can be used only as a base class of some other
class; no objects of an abstract class can be created except as
subobjects of a class derived from it ([basic.def], [class.mem]).
So as a static data member is a separate object relative to object of the class type where it is declared it can not be created as an object of an abstract class. On the other hand, when we are speaking about creating an object of a class type we mean its non-static data members that are sub-objects of the object of the class type. Static data members are instantiated independently of the instantiation of objects of the class where they are declared.

Literal class type member function constraints

The specification does not seem to put any constraints on the member functions of a literal class type
I have two questions regarding this
Q1) Do I have complete liberty over what member functions I can put in?
Q2) How do I verify if a class is a literal type? (Possible method: Define a constexpr object of it and check if it compiles?)
The only constraints on literal classes I see are:
• All the data members must have literal type.
• The class must have at least one constexpr constructor.
• If a data member has an in-class initializer, the initializer for a member of built-in type must be a constant expression, or if the member has class type, the initializer must use the member’s own constexpr constructor.
• The class must use default definition for its destructor, which is the member that destroys objects of the class type
(Source: C++ Primer, 5th edition)
Q1. Yes, you can have any methods you like (excluding constructor/destructor which have constraints). Even including virtual methods, if the constructor is constexpr.
Q2. As you say, define a constexpr variable of that type. If there is no diagnostic message (and the compiler is conforming) then the type is definitely a LiteralType. Note that it is possible for the type to be literal but the code to fail compilation for some other reason.
The definition in the Standard seems slightly clearer to me than your quoted definition. For example, there are some cases where a constexpr constructor is not required (e.g. a closure or an aggregate).

Deprecating static class members in C++11

I have come across different macros which enable deprecation of member attributes and functions but none of them discuss the possibility of deprecating static class members.
I read that even in C++14 deprecation of static members is not allowed.
Is there any specific reason for this?
Let's get some facts:
The wording for the [[deprecated]] attribute is the following
(based on N4269 7.6.5 [dcl.attr.deprecated], emphasis mine):
The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data
member, a function, a namespace, an enumeration, an enumerator, or a template specialization.
The misleading part is the explicit appearance of "non-static data members" without its counterpart at the same level in this list, but in that same list there are two other elements of interest.
The description of a variable is (based on 3 [basic]) :
A variable is introduced by the declaration of a reference other than a non-static data member or of an
object. The variable’s name, if any, denotes the reference or object.
Which means that saying a variable includes static data members
A static member function is a function (a red car is a car, this is a logical conclusion and i don't seem to find anything counter indicating this in the standard).
There isn't any syntax or behaviour problem applying particularly to static members, a static function is pretty much a free function in a namespace and static data member is more or less a global variable in a namespace and you can deprecate free functions and global variables..
As a bonus, it actually works in major compilers.
Summing up all this facts basically means that the [[deprecated]] attribute may actually be applied to a static data member, a non-static data member and a static member function, among other things.
So to answer your question, from my understanding, deprecating static members is actually allowed by the standard.

What exactly is a "member" of a class in C++?

I am new to C++, and have experience in Java and Python. I tried to search this question on Stack for a while, but did not find any questions that resembled this (although maybe that is because of my cursory knowledge of C++).
I was reading the C++ Primer book until I stumbled upon "members" of classes in C++. I can understand the concept of a class from Java, but I am unsure of what a "member" is.
Is a member simply an instance of a class? If so, how come it seems like the variables in a class are also considered members (in the Primer, the ISBN number of a class for a book is considered a member)?
Could anyone give a general definition of a "member" in C++?
A member is some entity that belongs to a class.
If a class has a function, this is a member function - you might know it as "a method".
If a class has a variable, this is a member variable - you might know it as "a property".
int a;
void f () {};
class A{
int m_A;
void m_F(){}
}
a is a global variable.
f is a global function.
m_A is a member variable or "property" of the class A.
m_F is a member function or "method" of the class A.
A member is defined as the variables and functions within a class.
Variables defined within a class are sometimes referred to as member variables. Similarly functions can be called member functions. Besides this, there isn't much to it.
According to the C++ Standard (9.2 Class members)
1 The member-specification in a class definition declares the full set
of members of the class; no member can be added elsewhere. Members of
a class are data members, member functions (9.3), nested types, and
enumerators. Data members and member functions are static or
non-static; see 9.4. Nested types are classes (9.1, 9.7) and
enumerations (7.2) defined in the class, and arbitrary types declared
as members by use of a typedef declaration (7.1.3). The enumerators of
an unscoped enumeration (7.2) defined in the class are members of the
class. Except when used to declare friends (11.3) or to introduce the
name of a member of a base class into a derived class (7.3.3),
member-declarations declare members of the class, and each such
member-declaration shall declare at least one member name of the
class. A member shall not be declared twice in the
member-specification, except that a nested class or member class
template can be declared and then later defined, and except that an
enumeration can be introduced with an opaque-enum-declaration and
later redeclared with an enum-specifier.
Also class members are
using-declaration
static_assert-declaration
template-declaration
alias-declaration
I guess a google search would have worked cause I just searched for 5 seconds:
Classes are an expanded concept of data structures: like data structures, they can contain data members, but they can also contain functions as members.
You can check a more complete definition here: http://www.cplusplus.com/doc/tutorial/classes/
In a nutshell both the data members (i.e variable of the class) and the functions are members of a class.
As far as I remember, java members are exactly the same.

Type of `this` in static member function?

In C++ 5.1.1/3 [expr.prim.general] it says:
The type and value category [of this] are defined within a static member function.
What does this mean? How is it relevant?
Note that:
this shall not appear in the declaration of a static member function
The language in the standard can be traced to n3282, which is a resolution for defects 1207 and 1017. In particular, the language appears in the proposed resolution for defect 1207, and thus should be considered in the context of the standard as it stood at the time that defect was addressed. At that time there was some concern over the rewriting of id-expressions into member access expressions using *this (9.3.1p3), in particular in the context of trailing-return-type declarations (see issue 945).
If we compare the proposed resolution to defect 1207 to the eventual language in n3282 and subsequently in the standard, there is one significant difference to 9.3.1p3:
Defect 1207:
When an id-expression (5.1 [expr.prim]) that is not part of a class member access syntax (5.2.5 [expr.ref]) and not used to form a pointer to member (5.3.1 [expr.unary.op]) is used in the declaration of a member function of class X, if name lookup (3.4 [basic.lookup]) resolves the name...
n3282 and C++11:
When an id-expression (5.1 [expr.prim]) that is not part of a class member access syntax (5.2.5 [expr.ref]) and not used to form a pointer to member (5.3.1 [expr.unary.op]) is used in a member of class X in a context where this can be used (5.1.1 [expr.prim.general]), if name lookup (3.4 [basic.lookup]) resolves the name [...]
It is apparent that the proposed resolution to defect 1207 carried the belief that id-expressions (to a static member) within a static member functions would need to be transformed to *this member access expressions and thus would need access to the type and value category of this. By the time n3282 was written this had been resolved in favour of the qualified-id transformation (also 9.3.1p3) which does not require this, but the language in 5.1.1p3 remained vestigially.
I would recommend raising this issue on the C++ standards discussion newsgroup; it may be possible to get the vestigial language removed editorially.