A Proposal to Improve const_iterator Use from C++0X Containers

Similar documents
Progress toward Opaque Typedefs for C++0X

Toward a Proposal for Object Templates in C++0x

A Proposal to Add Random-Number Distributions to C++0x

Named Requirements for C++0X Concepts

The C++ Standards Committee: Progress & Plans

Type Aliases. Examples: using newtype = existingtype; // C++11 typedef existingtype newtype; // equivalent, still works

by Pearson Education, Inc. All Rights Reserved. 2

A Proposal to Add a Logical Const Wrapper to the Standard Library Technical Report

A Proposal to Add a Const-Propagating Wrapper to the Standard Library

Advanced Programming in C++ Container Design I

Summary. Design. Layout

Proposing Standard Library Support for the C++ Detection Idiom, v2

Document Number: P0429R4 Date: Reply to: 0.1 Revisions... 1

A Standard flat_map. 1 Revisions. 2 Introduction. 3 Motivation and Scope. 1.1 Changes from R Changes from R0

use static size for this buffer

Refinements to basic_string

This chapter serves mainly to gather and organize information about iterators. Some new concepts are also introduced for completeness.

Decltype (revision 6): proposed wording

common_type and duration

Generalized pointer casts

Explicit Conversion Operator Draft Working Paper

Operator Overloading. Gary Powell, Doug Gregor, Jaakko Jȧ. rvi

Making std::vector constexpr

Lambdas in unevaluated contexts

Extending static_assert

Deducing the type of variable from its initializer expression (revision 4)

Wording for lambdas in unevaluated contexts

Doc. No.: WG21/N0937=X3J16/ Date: 28 May 1996 Project: C++ Standard Library Reply to: Nathan Myers

Deducing the type of variable from its initializer expression (revision 3)

Implicit Evaluation of auto Variables and Arguments

Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 2)

Botet C++ generic match function P0050

Tutorial 6. Y. Bernat. Object Oriented Programming 2, Spring Y. Bernat Tutorial 6

A Standard flat_set. This paper outlines what a (mostly) API-compatible, non-node-based set might look like.

C The new standard

Override Control Using Contextual Keywords

Tokens, Expressions and Control Structures

I m sure you have been annoyed at least once by having to type out types like this:

STL in Action: Helper Algorithms

The Syntax of auto Declarations

Lambdas in unevaluated contexts

Intermediate Programming, Spring 2017*

A Standard flat_map. Drop the requirement on container contiguity; sequence container will do.

Transformation Trait remove_cvref 1

ISO/IEC Systems and software engineering Systems and software Quality Requirements and Evaluation (SQuaRE) Planning and management

Lambda Expressions and Closures: Wording for Monomorphic Lambdas

Structured bindings with polymorphic lambas

Deducing the type of variable from its initializer expression Programming Language C++ Document no: N1721=

Implicit Evaluation of auto Variables and Arguments

Abstract This paper proposes the ability to declare multiple variables initialized from a tuple or struct, along the lines of:

Auxiliary class interfaces

Concepts for the C++0x Standard Library: Containers

September 10,

Extended friend Declarations

Programming in C++ using STL. Rex Jaeschke

Variables. Data Types.

Modeling variability with UML

Lambda Correctness and Usability Issues

Language Vulnerabilities Report: The Fortran Annex

explicit class and default definitions revision of SC22/WG21/N1582 =

Extended abstract. The Pivot: A brief overview

Dr. Md. Humayun Kabir CSE Department, BUET

Bring Back the Obvious Definition of count()

Information technology Database languages SQL Technical Reports. Part 4: SQL with Routines and types using the Java TM programming language

Appendix. Grammar. A.1 Introduction. A.2 Keywords. There is no worse danger for a teacher than to teach words instead of things.

Appendix. Compatibility. B.1 Introduction. You go ahead and follow your customs, and I ll follow mine. C. Napier

More STL algorithms (revision 2)

Abstract This paper proposes the ability to declare multiple variables initialized from a tuple or struct, along the lines of:

C++11: C++ AS CONTEMPORARY PROGRAMMING LANGUAGE

Absolute C++ Walter Savitch

COEN244: Class & function templates

National Body Comments ISO/IEC PDTS C++ Extensions for Transactional Memory

Evaluation Issues in Generic Programming with Inheritance and Templates in C++

C++ 11 and the Standard Library: Containers, Iterators, Algorithms

Introduction. Programming in C++ Pointers and arrays. Pointers in C and C++ Session 5 - Pointers and Arrays Iterators

Problem Solving with C++

Outline. 1 About the course

Fast Introduction to Object Oriented Programming and C++

Introduction to Standard C++

C++ Coding Standards and Practices. Tim Beaudet March 23rd 2015

Object-Oriented Programming for Scientific Computing

INTERNATIONAL STANDARD

More STL algorithms. Design Decisions. Doc No: N2569= Reply to: Matt Austern Date:

Class Types in Non-Type Template Parameters

Tutorial 7. Y. Bernat. Object Oriented Programming 2, Spring Y. Bernat Tutorial 7

Contract Programming For C++0x

These new operators are intended to remove some of the holes in the C type system introduced by the old C-style casts.

Axioms: Semantics Aspects of C++ Concepts

More on Templates. Shahram Rahatlou. Corso di Programmazione++

ISO/IEC INTERNATIONAL STANDARD

ISO/IEC INTERNATIONAL STANDARD. Information technology CDIF transfer format Part 3: Encoding ENCODING.1

ISO/IEC TR TECHNICAL REPORT. Software and systems engineering Life cycle management Guidelines for process description

Decltype (revision 5)

Simplifying C++0x Concepts

N2880 Distilled, and a New Issue With Function Statics

Lesson 13 - Vectors Dynamic Data Storage

Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 3)

Managing Memory. (and low level Data Structures) Lectures 22, 23. Hartmut Kaiser.

C++ Programming Fundamentals

Iterator Concepts for the C++0x Standard Library

Transcription:

A Proposal to Improve const_iterator Use from C++0X Containers Document #: WG21/N1674 = J16/04-0114 Date: August 31, 2004 Revises: None Project: Programming Language C++ Reference: ISO/IEC IS 14882:2003(E) Reply to: Walter E. Brown<wb@fnal.gov> CEPA Dept., Computing Division Fermi National Accelerator Laboratory Batavia, IL 60510-0500 Contents 1 Introduction 1 2 Proposal 3 3 Design alternatives 3 4 Proposed wording 5 5 Summary and conclusion 6 6 Acknowledgments 6 Bibliography 6 Sometimes a good idea comes to you when you are not looking for it. KARY B. MULLIS 1 Introduction This paper proposes to improve user access to the const versions of C++ container iterators and reverse_iterators. This proposal was initially motivated by an example that arose in conjunction with the proposals for decltype/auto [JSGS03, JS03, JS04]. Intended primarily to demonstrate the convenience aspect of the proposed new use for the auto keyword, that example exhibited such looping code as: 1 // Listing 1 4 for( auto it = v.begin(); it!= v.end(); ++it ) { 5 // use *it... In that context, the simple auto would replace today s rather unwieldy equivalent: 1

2 N1674: A Proposal to Improve const_iterator Use from C++0X Containers 1 // Listing 2 4 typedef vector<mytype>::iterator iter; 5 for( iter it = v.begin(); it!= v.end(); ++it ) { 6 // use *it... 7 } However, when a container traversal is intended for inspection only, it is a generally preferred practice 1 to use a const_iterator in order to permit the compiler to diagnose const-correctness violations: 1 // Listing 3 4 typedef vector<mytype>::const_iterator c_iter; 5 for( c_iter it = v.begin(), end = v.end(); it!= end; ++it ) { 6 f( *it ); // error if f takes its argument by non-const reference 7 *it = g(); // always an error 8 } If a formulation such as shown above more clearly expresses the programmer s intent, there ought to be a way to obtain such expression using the more convenient auto as proposed. Alas, we find no straightforward way of doing so at the moment. We initially felt that this counterexample demonstrated a weakness in the proposed use of auto. Upon further reflection, we now realize that the counterexample more likely demonstrates a weakness (i.e., an omission) in the iterators portion of the interfaces to today s standard containers [ISO03, Clause 23]. In particular, unless a container has been declared const, there is today no means of directly obtaining a const_iterator via a call to its begin member. Representative workarounds in common use today include (1) a const_cast of the container before calling begin, or (2) a (possibly implicit) static_cast of the iterator that results from such a call to begin: 1 // Listing 4 2 typedef vector<mytype> vect; 3 typedef vect::const_iterator c_iter; 4 vect v; 5 // alternatives: 6 c_iter it = const_cast<vect const &>(v).begin(); // 1 7 c_iter it = static_cast<c_iter>( v.begin() ); // 2 (explicit) 8 c_iter it = v.begin(); // 2 (implicit) Of these workaround alternatives, the implicit cast seems generally preferred by programmers. We postulate that this is due to the (deliberately) inconvenient syntax of modern C++ casts. We believe that programmers today lack a convenient means of directly expressing the use of a const_iterator in such contexts as we have described, and that the decltype/auto proposals would exacerbate such an omission from C++0X. It is not only in connection with the decltype/auto proposals that this omission manifests. Indeed, every input iterator argument to a generic nonmodifying algorithm (such as those in Clause 25, section [lib.alg.nonmodifying], and elsewhere) provides another context in which programmers might reasonably prefer to provide an instance of a const_iterator rather than of an iterator. The accumulate algorithm provides one common example: 1 As Herb Sutter succinctly exhorts, Be const correct. In particular, use const_iterator when you are not modifying the contents of a container [Sut05, p. 8].

N1674: A Proposal to Improve const_iterator Use from C++0X Containers 3 1 // Listing 5 2 vector<double> v; 4 cout << accumulate( v.begin(), v.end(), 0.0 ); The const-correctness aspect of type-safety would argue that it would be safer, in this example, to employ const_iterators than the iterators actually used above. 2 A second illustration focuses on a user error in the context of the for_each algorithm: 1 // Listing 6 2 void reset( double & d ) { d = 0.0; } 3 void resee( double d ) { cout << << d; } 4 vector<double> v; 5 // fill v... 6 for_each( v.begin(), v.end(), reset ); // oops: resee intended Such erroneous code is today typically not caught at compile-time. Were const_iterators furnished instead of iterators, contemporary compilers would routinely diagnose this form of erroneous usage. However, as noted previously, it is currently at best inconvenient for a programmer to obtain a const_iterator from a non-const container. 2 Proposal We believe that the C++ standard library should provide support, absent from C++03, so that a programmer can directly obtain a const_iterator from even a non-const container. We therefore propose to augment C++ containers interfaces with new (member) functions cbegin and cend, and with analogous (member) functions crbegin and crend: 1 // Listing 7 2 const_iterator cbegin() const; 3 const_iterator cend () const; 5 const_reverse_iterator crbegin() const; 6 const_reverse_iterator crend () const; 3 Design alternatives We believe that the desired functionality can be provided via either of two basic approaches. The alternatives are not mutually exclusive and, in fact, both could be adopted. (However, in Section 4 we provide proposed wording for our preferred Alternative 1 only.) Additionally, either alternative could, in theory, replace the const overloads of the extant container member functions begin, end, rbegin, and rend. This is because the proposed functions would subsume these overloads functionality. However, in order to preserve backwards compatibility, we prefer to retain all present forms of these member functions (although we are open to the possibility of deprecating their const overloads). 2 Indeed, it has been (emphatically!) argued to us that the standard library should diagnose the use of iterators-tonon-const in the context of calls to standard nonmutating algorithms. We suggest to revisit this notion should C++0X be augmented with some form of concept-checking for template arguments.

4 N1674: A Proposal to Improve const_iterator Use from C++0X Containers 3.1 Alternative 1: new container member functions This first alternative proposes to augment each standard library container template with four new member functions (cbegin, cend, crbegin, and crend) as described above. This would permit user code of the form: 1 // Listing 8 4 for( auto it = v.cbegin(), end = v.cend(); it!= end; ++it ) { 5 // use *it... We find such code very appealing, for it makes clear to a reader that the loop is non-mutating with respect to the container being traversed. We also note that use of these proposed member functions in an inappropriate context such as the earlier: 1 // Listing 9 2 void reset( double & d ) { d = 0.0; } 3 void resee( double d ) { cout << << d; } 4 vector<double> v; 5 // fill v... 6 for_each( v.cbegin(), v.cend(), reset ); // oops: resee intended would now yield a compile-time diagnostic as desired. 3.2 Alternative 2: new generic adapter templates This second alternative proposes to augment the standard library with four new function templates (cbegin, cend, crbegin, and crend) to provide a common interface to all containers. For example, a generic cbegin adapter might be implemented via a generic function such as: 1 // Listing 10 2 template< class C > 3 inline 4 typename C::const_iterator cbegin( C const & c ) { 5 return c.begin(); Availability of such adaptors would lead to client code of the form: 1 // Listing 11 4 for( auto it = cbegin(v), end = cend(v); it!= end; ++it ) { 5 // use *it... While this generic adapter alternative seems quite straightforward, we nonetheless favor the member function approach as proposed above. It seems more in keeping with current C++ programming idioms, such as the parallel use of rbegin as a container member function rather than as a generic adapter. We note that this generic adapter approach permits overloading so as to enable its use in connection with native arrays:

N1674: A Proposal to Improve const_iterator Use from C++0X Containers 5 1 // Listing 12 2 template< class T, size_t N > 3 inline 4 T const * cend( T const (& a)[n] ) { 5 return a + N; Whether this provides an advantage or a drawback is a matter of viewpoint. However, should this Alternative 2 be selected, then we would additionally propose, for consistency, to provide similar generic adapters for today s member functions begin, end, rbegin, and rend. 4 Proposed wording The following few additions constitute the necessary changes to standardize our recommended proposal (Alternative 1 above) with respect to C++03. Because analogous additions would be desirable for homogeneous sequential containers 3 that might in the future be adopted into C++0X, we intend that approval of the present proposal constitute authorization for the Project Editor to make such additions at the appropriate time. 4.1 Container requirements Add the following two new rows to Table 65 Container requirements in Clause 23, section [lib.container.requirements]: expression return type assertion/note... complexity a.cbegin(); const_iterator const_cast<x const &>(X).begin(); constant a.cend(); const_iterator const_cast<x const &>(X).end(); constant 4.2 Reversible container requirements Add the following two new rows to Table 66 Reversible container requirements in Clause 23, section [lib.container.requirements]: expression return type assertion/note... complexity a.crbegin(); const_reverse_iterator const_cast<x const &>(X).rbegin(); constant a.crend(); const_reverse_iterator const_cast<x const &>(X).rend(); constant 4.3 Synopses Add the following four declarations to the iterators part of Clause 21, section [lib.basic.string], as well as to the iterators parts of Clause 23, sections [lib.deque], [lib.list], [lib.vector], [lib.vector.bool], [lib.map], [lib.multimap], [lib.set], and [lib.multiset]: const_iterator const_iterator const_reverse_iterator const_reverse_iterator cbegin() const; cend() const; crbegin() const; crend() const; 3 For example, the unordered associative containers and fixed size arrays in [Aus04].

6 N1674: A Proposal to Improve const_iterator Use from C++0X Containers 5 Summary and conclusion This paper has described the utility of container begin and end variations whose return types are always const_iterators, independent of a container s constness. The paper has presented use cases based on today s C++03 as well as on the significant C++0X decltype/auto proposals. Two means of providing such missing functionality have been described herein: per-container member functions and generic adapter functions. In order to maintain parallelism with existing approaches, the former mechanism was recommended. Finally, this paper has proposed wording consistent with that recommendation. We respectfully urge the C++ standards bodies to consider our proposals in a time frame consistent with that of the forthcoming C++0X standard. 6 Acknowledgments I am pleased to acknowledge, with sincere thanks, a number of my Fermilab colleagues for their able advice and assistance during the production of this paper: Philippe Canal, Mark Fischler, Chris Green, John Marraffino, and Marc Paterno. I also wish to thank the Fermi National Accelerator Laboratory s Computing Division, sponsor of our participation in the C++ standards effort, for its support. Finally, many thanks to Richard Brown for his careful proofreading of several earlier drafts of this paper. Bibliography [Aus04] Matt Austern. (Draft) technical report on standard library extensions. Paper N1660, JTC1-SC22/WG21, July 16 2004. Online: http://www.open-std.org/jtc1/sc22/ wg21/docs/papers/2004/n1660.pdf; same as ANSI NCITS/J16 04-0100. [ISO98] [ISO03] Programming Languages C++, International Standard ISO/IEC 14882:1998(E). International Organization for Standardization, Geneva, Switzerland, 1998. 732 pp. Known informally as C++98. Programming Languages C++, International Standard ISO/IEC 14882:2003(E). International Organization for Standardization, Geneva, Switzerland, 2003. 757 pp. Known informally as C++03; a revision of [ISO98]. [JS03] Jaako Järvi and Bjarne Stroustrup. Mechanisms for querying types of expressions: Decltype and auto revisited. Paper N1527, JTC1-SC22/WG21, September 21 2003. Online: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/ n1527.pdf; same as ANSI NCITS/J16 03-0110. [JS04] Jaako Järvi and Bjarne Stroustrup. Decltype and auto (revision 3). Paper N1607, JTC1-SC22/WG21, February 17 2004. Online: http://www.open-std.org/jtc1/ sc22/wg21/docs/papers/2004/n1607.pdf; same as ANSI NCITS/J16 04-0047. [JSGS03] Jaako Järvi, Bjarne Stroustrup, Douglas Gregor, and Jeremy Siek. Decltype and auto. Paper N1478, JTC1-SC22/WG21, April 28 2003. Online: http://www.open-std. org/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf; same as ANSI NCITS/J16 03-0061. [Sut05] Herb Sutter. Exceptional C++ Style: 40 New Engineering Puzzles, Programming Problems, and Solutions. Addison-Wesley, Reading, MA, USA, 2005. ISBN 0-201-76042-8. xiv + 325 pp. LCCN QA76.73.C153S885 2005.