Bjarne, father of C ++, talks about the future development of C ++

Source: Internet
Author: User

Dynamic languages need to be constantly changed and growing, and C ++ is no exception. In this article, Bjarne Stroustrup puts forward his own views on the design and evolution of C ++.

In order to keep compilers, tools, and class library implementers up to date, and to allow users to absorb the programming technologies supported by standard C ++, after a few years of foresight and silence, the Committee once again considered the question of language extension." The extended working group has been established, which replaces the evolutionary Working Group ". Name changes (this is Tom Plum's suggestion) reflect more importantly the integration of language features and standard library tools. I am still the Chairman of the Working Group. I hope this will ensure the consistency of the C ++ version and the final result. Similarly, committee membership shows the continuous participation of a large number of people and organizations. Fortunately, many new faces have emerged, bringing new influences and new expert opinions to the Committee.

We intend to be cautious and conservative about changes in the language, with emphasis on compatibility. The main purpose is to direct the main efforts to the expansion of standard class libraries. In terms of standard libraries, our goal is to be bold and take advantage of all opportunities.

For a standard class library, I hope to establish it based on the elements of the class library technical report to make it a broader platform for system programming. For example, I want to see class libraries for some fields, such as directory/folder operations, threads, and sockets. I also hope that the Committee will sympathize with many new C ++ programmers and provide class library tools to support beginners with different backgrounds (not new programmers and C refugees ). For example, I want to see a standard method that uses the range check STL. I have very low expectations for the standard GUI (graphical user interface) that is most frequently requested to be added to the standard class library. However, miracles sometimes happen.-Do you remember STL?

For the language itself, I hope to emphasize the support for the features of generic programming, because generic programming is the most advanced field of language use. Here, I will investigate two key parts:

· Concept (Concepts): Type System Used for template parameters

· Initializer list: generalization of the initialization Tool

As in the past, the number of recommendations still far exceeds the number that the Committee can process and that language can absorb. Remember, it is impossible to accept all the good suggestions.
The purpose of this language extension to support generic programming is to provide greater consistency for tools, allowing us to directly represent classes used to solve problems with generics.

My other priorities (together with better support for generic programming) are better support for beginners. The current recommendations have a noteworthy tendency to take care of expert users who propose and evaluate suggestions. Some suggestions for helping new users are often ignored. I think this is a potentially fatal design preference. Unless the novice is fully supported, only a few can become experts. In addition, many people do not want to become experts; they still want to be "occasional C ++ users ". For example, physicists who use C ++ for physical computing or control test equipment spend only a limited amount of time learning programming techniques. Computer experts may spend a lot of time on programming technology, not just expectations. We must eliminate unnecessary obstacles to adopting excellent technologies.

An example is as follows:

Vector <double> v;
In C ++ of 98 years, this will lead to syntax errors, because> is a separate word mark, rather than two closed template parameter lists>. V's correct statement may be:

Vector <double> v;
I regard it as a hindrance. I once suggested that this problem should be solved, but the current rule and evolution Working Group used some good reasons to reject my suggestion twice. However, these reasons are both in terms of language technology, and new users (including experts in other languages) are not interested. Disaccepting the first (and very) Obvious v statement wastes user and instructor time. I hope> problems and other similar "obstacles" should not appear in C ++ 0x. Actually, together with Francis Glassborow and others, I am systematically trying to eliminate the most frequent "blocking ".

Another obstacle is that it is legal to copy class objects with user-defined destructor using the default copy operation (construction or assignment. In this case, user-defined replication operations are required to eliminate a large number of troublesome errors related to resource management. For example, consider the over-simplified string class below:

Class String {
Public:
String (char * pp): sz (strlen (pp), p (new char [sz + 1]) {strcpy (p, pp );}
~ String () {delete [] p ;}
Char & operator [] (int I) {return p [I];}
Private:
Int sz;
Char * p;
};
Void f (char * x)
{
String s1 (x );
String s2 = s1;
}
After s2 is constructed, s1.p and s2.p point to the same memory area, and this memory is deleted twice, which may cause disastrous consequences. This problem is obvious to experienced C ++ programmers who generally provide appropriate replication operations or prohibit replication. However, this problem will seriously affect new users and undermine their trust in the language.

Disabling the default replication behavior of class objects with pointer members may be better, but this may cause annoying compatibility issues. Fixing long-standing problems is much more difficult than the surface looks complicated, especially when considering C compatibility.

1. Concept (Concepts)

D & E (Editor's note: "Design and evolution of C ++" is generally referred to as D & E) the constraints on template parameters contained in the template discussion take up three full pages. Obviously, I think a better solution is needed. The error message caused by minor errors in the use of templates (such as standard library algorithms) may be very long and does not help us. This problem is because the template code absolutely believes in its own template parameters. Take a look at find_if () below ():

Template <class In, class Pred>
In find_if (In first, In last, Pred pred)
{
While (first! = Last &&! Pred (* first) ++ first;
Return first;
}
In the above Code, we make many assumptions about the In and Predicate types. We can see from the code that, for some reason, In must be supported with appropriate Semantics! =, * And ++, and we must be able to copy In objects as parameters and return values. Similarly, we can see that we can call a Pred. Its parameter is * (value operator) of any type returned from In and applied to the result! Operator, which can be regarded as boolean. However, all these are implicit in the code. The standard library carefully records these requirements of the forward iterator sub (In this example) and the Pred, but the compiler does not read the manual. Try the following error to see the error message displayed by your Compiler:

Find_if (3.14,); // Error
The solution based on my old idea-let the constructor check the hypothetical conditions of template parameters-is currently widely used. For example:

Template <class T> struct forward_iterator {
Static void constraints (t ){
++ A; A ++; // you can add
T B = A; B = A; // copy
* B = * A; // The result can be discarded or copied.
}
Forward_iterator () {void (* p) (t) = constraints ;}
};
The code above defines a class, which can be compiled only when T is a forward iterator. However, the forward_iterator object does not perform any actual transactions, so the compiler can only (and indeed) perform minor optimization operations on such objects. We can use forward_iterator in the following definition:

Template <class in, class Pred>
In find_if (in first, in last, PRED Pred)
{
Forward_iterator <in> (); // check the template parameter type.
While (first! = Last &&! PRED (* First) ++ first;
Return first;
}
Alex Stepanov and Jeremy Siek have done a lot of work to develop and popularize this technology. One of the places they use this technology is the Boost class library, but currently you will find the constraint class in most standard class library implementations. The quality of error messages varies greatly.

However, the constraint class is an incomplete solution at most. For example, test in definition-if the check can only be completed in declaration, it will be much better. When using this method, we must follow the Interface Usage rules and begin to consider the possibility of separate template compilation.

Therefore, let's tell the compiler the template parameters we expect:

Template <Forward_iterator In, Predicate Pred>
In find_if (In first, In last, Pred pred );
Suppose we can indicate what Forward_iterator and Predicate are, then the compiler can ignore its definition and independently check the find_if () call. In this case, we need to create a type system for the template parameters. In modern C ++ environments, this "type of type (types of types)" is called "concept (concepts )". We can illustrate this concept in many ways. From now on, we want to think of them as constraints that are directly supported by languages and have better syntax. A concept illustrates what tools are required for a type, rather than how they are provided. The concept of perfection (for example, <Forward_iterator In>) is very similar to that of mathematical abstraction ("In can be added, destroyed, and replicated for all types of In, just as the original <class T> is mathematical "for all types of T ".

After the find_if () Statement is given (and not defined), we can write

Int x = find_if (1, 2, Less_than <int> (7 ));
This call will fail because int does not support *. In other words, this call fails during compilation because Int Is Not A forward_iterator. It makes it easy for the compiler to report errors in the user language, and the call will be first seen during compilation.

Unfortunately, knowing that the sub-parameter of iteration is forward_iterator and that the predicate parameter is not enough to ensure that find_if () is successfully compiled. These two parameters affect each other. In particular, the PRED parameter is an iterator that uses * (PRED (* First) to release the reference. Our goal is to improve the template detection in the case of separation from the call, and improve the inspection of each call without viewing the template definition, therefore, the concept must have sufficient performance to process such iterations in template parameters. One way is to use parallel parameters to represent the concept, which is similar to the parameterization method of the template. For example:

Template <value_type t,
Forward_iterator <t> In, // The iterator is in the T sequence.
Predicate <bool, T> Pred> // carries the t parameter and returns a Boolean value.
In find_if (in first, in last, PRED Pred );
In the preceding code, forward_iterator must point to the element of type T, which is also the parameter type of predicate.

Common parameters (here, the parameter t) are used to express the necessary relationship between template parameters. Unfortunately, they do not have powerful performance capabilities. As a result, we add template parameters and indirectly (cannot directly) express requirements. For example, the preceding example does not indicate that it is feasible to pass the * first result as a parameter to Pred. In fact, it indicates that forward_iterator and predicate share a template parameter type. To solve such problems, we are studying the possibility of directly expressing the relationship between template parameters. For example:

Template <Forward_iterator In, Predicate Pred>
Where (assignable <In: value_type, Pred: argument_type>)
In find_if (In first, In last, Pred pred );
This method also has its own problems. For example, its requirements (where clause) tend to increase the complexity of the template definition itself, and popular iterations (such as int *) does not have a member type (such as value_type ).

One possible expression of the concept is to directly support the constraints class we used in the past. For example, we use the following method to define the Forward_iterator used in the preceding example:

Template <class T> concept Forward_iterator {
// Parameterized Concept
Forward_iterator;
++ A; a ++; // you can add
Forward_iterator B = a; // you can copy
* B = * a; // The result can be abolished and copied.
T x = * a; * a = x; // The result is T type.
};
Or

Concept forward_iterator {// The concept is not represented by a parameter
Forward_iterator;
++ A; A ++; // you can add
Forward_iterator B = A; B = A; // you can copy
* B = * A; // The result can be abolished and copied.
};
The concept definition of parameterization can be used for the first declaration of find_if, and for the second declaration without parameters. They represent a replaceable language design. We will also provide some design options in this field. However, let's look at the following situation:

Int x = find_if (1, 2, less_than <int> (7 ));
This is unqualified, because 1 and 2 are of the int type, and INT does not support *. If we use the parametric design concept, it is also unqualified, because Int Is Not A parameterized type that can match forward_iterator <t>. On the other hand, let's look at the following example:

Void F (vector <int> & V, int * P, int N)
{
Vector <int>: iterator q = find_if (V. Begin (), V. End (), less_than <int> (7 ));
Int * q2 = find_if (p, p + N, less_than <int> (7 ));
//...
}
Obviously, I am reporting what is currently being done, but some form of concept is likely to become the cornerstone of C ++ 0x. Templates have become the most effective (and efficient) elements of the C ++ programming style, but they suffer from a lot of troubles: a large number of useless error messages, there is a lack of tools to overload templates based on template parameters, and poor compilation. The concept directly solves all these problems, and there is no major defect in abstract base classes based on methods-performance overhead for parsing when calling through virtual functions. It is important that the concept does not depend on the explicitly declared sub-type hierarchy. Therefore, logical redundancy is not required, and built-in types and classes can be considered equal.

Nowadays, there are a wide range of papers focusing on concepts and possible relationships between them and similar structures in other languages. Matt austern, jaako J? RVI, Mich Marcus, Gabriel dos Reis, Jeremy siek, Alex Stepanov, and I are active in this design issue.

2. Generalized initializer

A basic idea of C ++ is to "support user-defined types as well as built-in types ". However, let's look at the following situation:

Double VD [] = {1.2, 2.3, 3.4, 4.5, 5.6 };
Vector <double> V (VD, VD + 5 );
We can use the list of initiators to initialize the array. However, for vector, the best way to do this is to create an array and use this array to initialize the vector. If there are only a few initiatorvalues, I may even use the following method to avoid explicitly describing the number of initiatorvalues (5 in the above example ):

Vector <double> V;
V. push_back (1.2 );
V. push_back (2.3 );
V. push_back (3.4 );
V. push_back (4.5 );
V. push_back (5.6 );
I don't think anyone can use any of the above solutions as appropriate. To get the code that is the easiest to maintain and prevent the built-in (and inherently dangerous) arrays from getting "favored" More vectors than the recommended user-defined types, we can write the following code:

Vector <double> V = {1.2, 2.3, 3.4, 4.5, 5.6 };
Or

Vector <double> V ({1.2, 2.3, 3.4, 4.5, 5.6 });
Since parameter passing is defined during initialization, this is also feasible for functions with vectors:

Void F (const vector <double> & R );
//...
F ({1.2, 2.3, 3.4, 4.5, 5.6 });
I believe that the generalization of the initialization tool will become part of C ++ 0x. It will become part of the constructor check work, because many of the defects found by people seem to be solved by generalization of Constructor (such as forwarding constructor, guaranteed constructor during compilation, and inherited constructor.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.