HP aC++ A.03.30 largely conforms to the
ISO/IEC 14882 Standard for the
C++ Programming Language (the international standard for C++).
Choose from the following for more information:
Migration
|
|
-
or
-
or_eq
-
private
-
protected
-
public
-
reinterpret_cast
-
static_cast
-
template
-
this
-
throw
-
true
-
try
-
typeid
-
typename
-
using
-
virtual
-
volatile (also an ANSI C keyword)
-
wchar_t
-
xor
-
xor_eq
|
The keyword bool represents a data type. Variables and expressions
of type bool can have a value of either true or false.
The value of true equals 1. The value of false equals 0.
Usage
The ANSI/ISO C++ International Standard states that values of type bool are either true
or false.
There are no signed, unsigned, short, or long bool types or values.
bool values behave as integral types and participate in integral promotions.
Types bool, char, wchar_t, and the
signed and unsigned integer types are collectively called integral types.
A synonym for integral type is integer type. The representations of
integral types shall define values by use of a pure binary numeration system.
Example
void main(){
bool b=true; // Declare a variable of type bool and set it to true.
if (b) // Test value of bool variable.
b=false; // Set it to false.
}
The keyword dynamic_cast is used in expressions to check the safety of a
type cast at runtime. It is the simplest and most useful form of runtime
type identification. You can use it to cast safely within a class hierarchy
based on the runtime type of objects that are polymorphic types
(classes including at least one virtual function). At
runtime, the expression being cast is checked to verify that it points to
an instance of the type being cast to.
Usage
A dynamic cast is most often used to cast from a base class pointer
to a derived class pointer in order to invoke a function appearing only
in the derived class. Virtual functions are preferred when their mechanism
is sufficient.
Usually a dynamic cast is necessary because the base class is
being specialized, but can't (or shouldn't) be modified.
class Base {
virtual void f(); // Make Base a polymorphic type.
// other class details omitted
};
class Derived : public Base {
// class details omitted
};
void Base::f()
{
// define Base function
}
void main()
{
Base *p;
Derived *q;
Base b;
Derived d;
p = &b;
q = dynamic_cast (p); // Yields zero.
p = &d;
q = dynamic_cast (p); // Yields p treated
// as a derived pointer.
}
Static and dynamic casts are used to move within a class hierarchy.
Static casts use only static (compile-time) information to do the conversions.
In the example above, if p is really pointing to an object of type Derived,
either a static or dynamic cast of p to q yields the same result.
This is also true if p were the null pointer. But, if
p is not pointing to an object of type Derived, a dynamic cast returns zero,
and a static cast returns a stray pointer.
Dynamic casts must be done to a pointer or reference type.
For example, if the cast above is written as:
q = dynamic_cast (p);
The compile time error message is:
The result type of a dynamic cast must be a pointer or
reference to a complete class; the actual type was Derived.
If you attempt a dynamic cast from a non-polymorphic type,
you will also get a compile-time error. For example:
class Base {
// class details omitted
};
class Derived : public Base {
// class details omitted
};
void main()
{
Base *p;
Derived *q;
Base b;
p = &b;
q = dynamic_cast (p);
}
The above generates a compile-time error stating that:
Dynamic down-casts and cross-casts must start from a polymorphic class
(one that contains or inherits a virtual function); but class Base is
not polymorphic.
The syntax of conditions allows declarations in them. For example:
class Base {
virtual void f(); // Make Base a polymorphic type
// other class details omitted
};
class Derived : public Base {
public:
void derivedFunction();
// other class details omitted
};
void Base::f()
{
// Define Base function.
}
void Derived::derivedFunction()
{
}
void main()
{
Base *p = new Derived;
// details omitted
if (Derived *q = dynamic_cast (p))
q->derivedFunction(); // use derived function
}
You can use dynamic casts with references as well. Since a reference can't
be zero, when the cast fails it raises a Bad_cast exception.
Before the implementation of the dynamic cast operator, you could not cast
from a virtual base class to one of its derived classes because
there was not enough information in the object at runtime to do this cast.
Once runtime type identification was added, however, the information stored
in a polymorphic virtual base class is sufficient to allow a dynamic cast
from this base class to one of its derived classes. For example:
class Base1 {
// Not a polymorphic type.
// additional class details omitted
};
class Base2 {
virtual void f(); // Make Base2 polymorphic.
// additional class details omitted
};
void Base2::f()
{
// Define Base2 function.
}
class Derived : public virtual Base1, public virtual Base2 {
// additional class details omitted
};
void main()
{
Base1 *bp1;
Base2 *bp2;
Derived *dp;
bp1 = new Derived;
bp2 = new Derived;
// dp = (Derived *) bp1; // Problem: compile time error
// Can't cast from virtual base.
// dp = (Derived *) bp2; // Problem: compile time error
// Can't cast from virtual base.
// dp = dynamic_cast bp1; // Problem: compile time error
// Can't cast from
// non-polymorphic type.
dp = dynamic_cast bp2; // OK
}
The explicit keyword is used for declaring constructor functions within class
declarations. When these functions are declared explicit,
they cannot be used for implicit conversions.
Usage
While constructors taking one argument are often useful in the design of
a class, they can allow inadvertent
conversion in expressions. This can introduce subtle bugs.
The explicit keyword allows a class designer to prohibit
such implicit conversions. It is often used in the production of
class libraries.
class C {
public:
explicit C(int);
};
C::C(int)
{
// empty definition
}
void main()
{
C c(5); // Legal
c = C(10); // Legal
// c = 15; // Produces a compile time error:
// Message: Cannot assign 'C' with 'int'.
// c + 20; // Produces a compile time error
}
A classic example of this problem is an array class:
class Vector {
public:
Vector(int n); // create a vector of n items
// other class details omitted
};
void main()
{
Vector operator + (Vector, Vector);
Vector v1(10), v2(10); // create two 10 element vectors
// details omitted
v1 = v2 + 5; // Legal - converts int 5 to a 5
// element vector and adds to v2.
// Not something you want to be
// legal
}
With the explicit keyword, the constructor can be made explicit and
the declarations are legal, but the addition is a compilation error:
class Vector {
public:
explicit Vector(int n); // create a vector of n items
// other class details omitted
};
void main()
{
Vector operator + (Vector, Vector);
Vector v1(10), v2(10); // create two 10 element vectors
// details omitted
// v1 = v2 + 5; // Not legal - generates compile-
// time error
// Message: Illegal types
// associated with operator '+':
// 'Vector' and 'int'.
}
The mutable keyword is used in declarations of class members.
It allows certain members of constant objects to
be modified in spite of the constness of the containing object.
Usage
Often some class members are part of the implementation of the object,
not part of the actual information stored by the object.
Although the information in the object needs to stay unmodified in
a const object, the
implementation members may need to change. These are declared mutable.
An example of this is a use or reference count in an object that keeps
track of the number of pointers referring to it.
class C {
public:
C();
int i;
mutable int j;
};
C::C() : i(1), j(3)
{
// Define constructor
}
void main()
{
const C c1;
C c2;
// c1.i =0; // Problem: compilation error
// Message: The left side of '=' must be
// a modifiable lvalue.
c1.j = 1; // OK
c2.i = 2; // OK
c2.j = 3; // OK
}
The mutable keyword can only be used on class data members.
It cannot be used for const or static data members. Notice the
difference in the two pointer declarations below:
class C {
C() { } // define constructor
mutable const int *p; // OK
// mutable pointer to int const
// p in constant C object can be modified
mutable int *const q; // Compile time error
// mutable const pointer to int
// const data member can't be mutable
// Message: 'mutable' may be used only
// in non-static and non-constant data
// member declarations within class
// declarations.
};
Namespaces were introduced into C++ primarily as a mechanism to
avoid naming conflicts between various libraries. The example
below illustrates how this is achieved.
As can be seen, every namespace introduces a new scope.
By default, names inside a namespace are hidden from enclosing scopes.
Selection of a particular name can be achieved using the
qualified-name syntax.
Namespaces can be nested very much like classes.
#include
namespace N {
struct Object {
virtual char const* name() const { return "Object from N"; }
};
}
namespace M {
struct Object {
virtual char const* name() const { return "Object from M"; }
};
namespace X { // a nested namespace
struct Object: M::Object { // inherit from a class in the outer space
char const* name() const { return "Object from M::X"; }
};
}
}
int main() {
N::Object o1;
M::Object o2;
M::X::Object o3;
printf("This object is: %s.\n", o1.name());
printf("This object is: %s.\n", o2.name());
printf("This object is: %s.\n", o3.name());
return 0;
}
If a type, function, object, etc. is declared inside of a namespace,
then using that entity will require naming this namespace in some
explicit or implicit way; even if the use happens in another translation
unit (or source file).
One somewhat unique feature of namespaces is that they can be extended.
The example below shows this as well as the connections between
a namespace extending across different translation units.
The example also illustrates the concept of so-called unnamed
namespaces. These namespaces can only be extended within a
translation unit. Unnamed namespaces in different translation
units are unrelated; hence their names effectively have internal
linkage. In fact, the ANSI/ISO C++ International Standard
specifies that using static to indicate internal linkage is
deprecated in favor of using namespaces.
#include
namespace N {
char const* f() { return "f()"; }
}
namespace { // An unnamed namespace
char const* f(double);
} // Names in unnamed namespaces are visible in their surrounding scope.
// They cannot be qualified since the space has no name.
namespace N { // An extension of the first part of namespace N
char const* f(int); // Leave the implementation to another
} // translation unit.
int main() {
printf("Calling: %s.\n", N::f()); // OK, declared and defined above
printf("Calling: %s.\n", N::f(7)); // OK, declared above (defined elsewhere)
printf("Calling: %s.\n", f(3.0)); // OK, declared above (defined below)
return 0;
}
namespace { // An extension of the unnamed namespace in this translation unit
char const* f(double) { return "f(double) in main() translation unit"; }
}
An Auxiliary Translation Unit
Following is an auxiliary translation unit that illustrates how namespaces
interact across translation units.
namespace { // An unnamed namespace unrelated to the one in the other
// translation units.
char const* f(double) { return "f(double) in auxiliary translation unit"; }
}
namespace N { // This namespace is the same as the one in the main()
// translation unit. We implement f(int) here.
char const* f(int) { return "f(int) defined in auxiliary translation unit"; }
}
The C++ provides two alternatives to explicitly qualifying names
in namespaces. These are the using-declaration and the using-directive.
using-declaration
A using-declaration introduces a declaration in the current scope as follows:
using N::x; // Where N is a namespace, x is a name in N
After this declaration, all uses of x in this scope are taken to
defer to N::x. (The N:: prefix is no longer required.)
If another declaration of x were introduced in the same scope, for example:
int x;
then a compiler error would occur.
using-derective
The using-directive directs the lookup for names not declared in current
scope, for example:
using namespace N; // If not found, lookup names in namespace N
If x is a name in namespace N, but another declaration of x is present
in the current scope, for example:
int x;
a compiler error is not necessarily emitted. Only if that name is used
will an ambiguity occur.
CAUTION:
Using-directives are transitive. If you specify a using-directive to
one namespace which itself specifies a directive to another namespace,
then names used in your scope will also be looked up in that other
namespace.
Using namespace directives can be a powerful means to migrate code to
libraries that use namespaces. Occasionally, however, they may silently
make unwanted names visible. It is therefore often suggested not to use
using-directives unless the alternatives are very inconvenient.
#include
namespace N {
char const* f() { return "N::f()"; }
char const* f(double) { return "N::f(double)"; }
char const* g() { return "N::g()"; }
}
char const* g(double) {
using N::f; // Declare all f's in namespace N
return f(2.0);
}
namespace M { // Illustrate how using-directives
using namespace N; // are transitive
}
int main() {
using namespace N;
printf("Calling: %s.\n", f()); // calls N::f()
printf("Calling: %s.\n", g(1.0)); // calls ::g(double)
// which calls
// N::f(double)
printf("Calling: %s.\n", N::g()); // calls N::g()
printf("Calling: %s.\n", M::f()); // calls N::f()
return 0;
}
The typeid keyword is an operator, called the type identification operator,
used to access type information at runtime. The operator takes either
a type name or an expression and returns a reference to an instance of
type_info, a standard library class.
Usage
You can use runtime type identification when you need to know the
exact type of an object. This might, for example, be necessary to find
the name of the object class for diagnostic output. It also might be used
to perform some standard service on an object such as via a database or
I/O system.
For More Information
# include
# include
class Base {
virtual void f(); // Must have a virtual function to
// be a polymorphic type.
// additional class details omitted
};
class Derived : public Base {
// class details omitted
};
void Base::f()
{
// Define function from Base.
}
void main ()
{
Base *p;
// Code which does either
// p = new Base; or
// p = new Derived;
// Note that this is NOT a good design for this functionality.
// Virtual functions would be better.
if (typeid(*p) == typeid(Base))
cout << "Base Object\n";
else if (typeid(*p) == typeid(Derived))
cout << "Derived Object\n";
else
cout << "Another Kind of Object\n";
}
If a typeid operation is performed on an expression that is not a polymorphic
type (a class which declares or inherits a virtual function),
the operation returns the static (compile-time) type of the expression. In the
example above, if class Base did not include the virtual function f(),
typeid(p) would always yield the type Base.
The style of programming used in the above example might be called a typeid
switch statement. It is not generally a reasonable design.
One alternative is to use a virtual function in a base class specialized in
each of its derived classes. In some cases, this may not be possible,
for example, when the base class is provided by a
library for which source code is not available.
In other cases it may not be desirable, for example, some base
class interfaces might be too big if all derived class functionality is
included.
You could rewrite the above example, using virtual functions, as:
class Base {
virtual void outputType() { cout << "Base Object\n"; }
// additional class details omitted
};
class Derived : public Base {
virtual void outputType() { cout << "Derived Object\n"; }
// additional class details omitted
};
void main ()
{
Base *p;
// code which does either
// p = new Base; or
// p = new Derived;
p->outputType();
}
A second alternative is to use a dynamic cast. In many cases, this alternative
is less desirable than using virtual functions, but it is better than
a typeid switch statement in nearly every case. There is a subtle difference
between this alternative and the typeid switch statement above.
The typeid operation allows access to the exact type of an object;
a dynamic cast returns a non-zero result for the target type or a type
publicly derived from it.
You could rewrite the above example as follows using dynamic casts:
class Base {
virtual void f(); // Must have a virtual function to
// be a polymorphic type.
// additional class details omitted
};
class Derived : public Base {
// class details omitted
};
void Base::f()
{
// Define function from Base.
}
void main ()
{
Base *p;
// code which does either
// p = new Base; or
// p = new Derived;
if (dynamic_cast (p))
cout << "Derived (or class derived from Derived) Object\n";
else
cout << "Base Object\n";
}
The keyword volatile is used in declarations. It tells the compiler
not to do aggressive optimization because a value might be changed
in ways the compiler couldn't detect.
This keyword is part of the ANSI C standard with the same syntax and semantics.
Usage
Objects that are hardware addresses or those used by concurrently executing
pieces of code are frequently declared volatile. Examples are an address
used for the current clock time, objects used by a signal handler, or
objects used for memory mapped I/O.
Note, you can declare an identifier to be both const and volatile. This
declares a value that the program cannot change but which can be changed
by some means external to the program (such as by a piece of hardware like a
clock).
Example Code with Discussion
class C {
public: // public to make example simpler
volatile int i;
// other class details omitted
};
C someData[10];
void main ()
{
int j = someData[5].i;
j = someData[5].i; // Without the volatile specifier, the
// compiler could optimize these two
// statements into one. With it, it must
// execute both in case the i field of
// someData[5] has changed by some
// other means.
}
Wide (or multi-byte) characters can be declared with the data type wchar_t.
It is an integral type that can represent all the codes of the largest
character set among the supported locales defined in the localization library.
This keyword was part of the ANSI C standard.
Usage
This type was added to maintain ANSI C compatibility and to accomodate foreign
(principally Oriental) character sets.
Example Code with Discussion
In the following example, literals of type wchar_t consist of the
character L followed by a character constant in single quotes.
void main()
{
wchar_t ch = L'a';
}
wchar_t must be implemented the same as another integral type.
In other words, it must have the same size,
signedness and alignment requirements. It promotes to the smallest integral
type when used in an expression
and cannot have a signed or unsigned modifier.
The standard library includes a string of wide characters known as wstring.
The IOStream library supports I/O of wide characters.
In ANSI C, wchar_t is a synonym for another type, declared using a
typedef in a standard header file.
Use the typename keyword in template declarations to specify that
a qualified name is a type, not a class member.
Usage
This construct is used to access a nested class in the template parameter class as a type in a declaration within the template.
Example Code
template
class C1 {
// class details omitted
// T::C2 *p; // Problem: flagged as compile-time
// error. T is a type, but T::C2 is not.
// Message: 'C2' is used as a type, but
// has not been defined as a type.
typename T::C2 *p; // Solution: the keyword typename flags
// the qualified name T::C2 as a type.
};
class C {
// details omitted
class C2 {
//details omitted
};
};
void main ()
{
C1 c;
}
Discussion
In a template, a name is not taken to be a type unless it is explicitly
declared as one. Ways to declare a name as a type include:
- Use it as the argument to the template (T below):
template
class C {
// Additional details omitted
};
- Use it as the name of the template (C below):
template
class C {
// Additional details omitted
};
- Declare a class as a member of the class template (C2 below):
template
class C1 {
class C2;
// Additional details omitted
};
- Declare a class in the context the template is declared within (C1 below):
class C1;
template
class C2 {
// details omitted
};
HP aC++ defines new and delete operators for arrays that are different from
those used for single objects.
These operators, operator new[ ] ( ) and operator delete[ ] ( ),
can be overloaded both globally and in a class.
If you use operator new( ) to allocate memory for a single object,
you should use operator delete( ) to
deallocate this memory. If you use operator new[ ] ( ) to allocate an array,
you should use operator delete[ ] ( ) to deallocate it.
Usage
Usually, the allocation and deallocation of operators is overloaded for a
particular class, not globally. This overloading allows you to put all
instances of a particular class on a class-specific heap. You can then take
control of allocation either for efficiency or to accomplish other storage
management functions, for example garbage collection. If allocation and
deallocation of single objects is overloaded, you may or may not want to
overload the operators for arrays. If the overloading was done for efficiency,
it may be that for arrays the default operator is the most efficient.
For More Information
# include
class C {
public:
void* operator new[ ] (size_t); // new for arrays
void operator delete[ ] (void*); // delete for arrays
// additional class details omitted
};
void* C::operator new[ ] (size_t allocSize)
{
cout << "Use operator new[ ] from class C\n";
// here, real usage would include allocation
return ::operator new[ ] (allocSize); // global operator
} // for this simple example
void C::operator delete[ ] (void *p)
{
cout << "Use operator delete[ ] from class C\n";
// here, real usage would include deallocation
::operator delete[ ] (p); // global operator
} // for this simple example
void main()
{
C *p;
p = new C[10];
delete[ ] p;
}
Notice that the new operator takes a class with an array specifier as an
argument. The compiler uses the class
and array dimension to provide the size_t argument. In the example above,
the argument provided is ten times the size of a class C object.
Also, the operator must return a void* which the compiler converts to
the class type. The void constructor for the class (if one exists)
is invoked to initialize the elements in the array.
Multidimensional arrays can be allocated and deallocated with these operators.
The operator is used with several array dimensions, and
the compiler provides the size_t argument which is the space required for
the entire array. For example:
// call C::operator new[ ] ( ) with
// an argument of 10 * 20 * sizeof(C)
p = new C [10] [20];
Additional arguments can be provided to this operator new just as for the
operator for single objects. In this way, the operator can be overloaded in a
class. The additional arguments can be used by the storage allocation scheme
for additional storage management.
The global new and delete for both arrays and single objects are provided
in the Standard C++ Library. This library also provides a version of
new for arrays and single objects that takes a second void* argument and
constructs the object at that address.
Classes are provided in the Standard C++ Library to report program errors.
These classes are declared in the <stdexcept> header. All of these classes
inherit from a common base class named exception.
The two classes logic_error
and runtime_error inherit from exception and serve as base classes for more
specific errors.
Usage
These classes provide a common framework for the way errors are handled
in a C++ program.
Systen-specific error handling can be provided by creating classes that
inherit from these standard exception classes.
Example
# include
# include
# include
void f()
{
// details omitted
throw range_error(string("some info"));
}
void main()
{
try {
f();
}
catch (runtime_error& r) {
// handle any kind of runtime error including range_error
cout << r.what() << '\n';
}
}
Discussion
The class logic_error defines objects thrown as exceptions to report errors
due to the internal logic of the program. The errors are presumably preventable
and detectable before execution. Examples are violations of logical
preconditions or class invariants. The subclasses of logic_error are:
- domain_error (the operation requested is inconsistent with the state of the
object it is applied to)
- invalid_argument
- length_error (an attempt to create an object whose size equals or exceeds
allowed size)
- out_of_range (an argument value not in the expected range).
Runtime errors are due to events out of the scope of the program. They cannot
be predicted before they happen.
The subclasses of runtime_error are:
- range_error
- overflow_error (arithmetic overflow)
The exception class includes a void constructor, a copy constructor,
an assignment operator, a virtual destructor, and a function what() that
returns an implementation-defined character string. None of these
functions throw any exceptions.
Each of the subclasses includes a constructor taking an instance of the
Standard C++ Library string class as an argument. They initialize an instance such that the
function what(), when applied to the instance, returns a
value equal to the argument to the constructor.
The following exceptions are thrown by the Standard C++ Library.
CAUTION:
If no catch clauses are available to catch these exceptions,
the default action is program termination with a call to abort().
(Note that using the +noeh option does not disable the
exceptions thrown by these library functions.)
-
operator new () and operator new [ ] throw a bad_alloc exception
when they cannot obtain a block of storage.
- A
dynamic_cast expression throws a bad_cast exception when a cast
to a reference type fails.
- Operator
typeid throws a bad_type exception when a pointer
to a typeid expression is zero.
- A
bad_exception exception can be thrown when the unexpected
handler function is invoked by unexpected().
Usage
You need to write try/catch clauses to handle the standard exceptions.
For an example, refer to
Memory Allocation Failure and operator new.
type_info is a class in the standard header file <typeinfo>.
A reference to an instance of this class is returned by the
typeid operation. Implementations may
differ in the exact details of this class, but in all cases it is a
polymorphic type (has virtual functions) that allows comparisons and
a way to access the name of the type.
Usage
This class is useful for diagnostic information and for implementing services
on objects where it is necessary to know the exact type of the object.
Example
# include
# include
class Base {
virtual void f(); // Must have a virtual function to
// be a polymorphic type
// additional class details omitted
};
class Derived : public Base {
// class details omitted
};
void Base::f()
{
// Define function from Base.
}
void main ()
{
Base *p;
// code which does either
// p = new Base; or
// p = new Derived;
if (typeid(*p) == typeid(Base)) // Standard requires
// comparison as part of
// this class.
cout << "Base Object\n";
cout << typeid(*p).name() << '\n'; // Standard requires access to
// the name of the type.
}
The standard requires the class type_info to be polymorphic. You
can't assign or copy instances of the class
(the copy constructor and assignment operators are private).
The interface must include:
int operator == (const type_info&) const
int operator !=( const type_info&) const
const char * name() const
int before (const type_info&) const
The operators allow comparison of object types. The name() function allows
access to the character string representing the name of the object.
The before function allows types to be sorted. This allows them to
be accessed through hash tables. The before function is not a lexical ordering; it might not yield the same results
Functionality defined in the ANSI/ISO C++ International Standard and not supported in this
release of HP aC++ is listed below.
Library functionality is listed separately.
NOTE:
These are not all inclusive lists.
- covariant return types with multiply inheriting types
- Template Features
- separation model for template compilation (
export keyword)
- template template parameters
- omission of template parameter names
- support for universal-character-sequences (\uxxxx)
| Functionality |
Rogue Wave Standard C++ Library 2.2.1 |
Rogue Wave Standard C++ Library 1.2.1 |
libc.sl
and libc.a
(HP-UX System Libraries)
|
| <allocator> |
Yes. |
Provided as a class rather than a template. |
Not applicable. |
| <cstring> |
Yes. |
The following C++ overloaded functions are not provided,
instead, ANSI C signatures are implemented.
-
memchr
-
strchr
-
strpbrk
-
strrchr
-
strstr
|
Not applicable. |
| <cwchar> |
Yes. |
The following C++ overloaded functions are not provided,
instead, ANSI C signatures are implemented.
Missing functions:
|
For missing functions, see
wide character support in this table. |
| <cwctype> |
Partial support. |
Partial support. |
See wide character support in this table. |
| <functional> |
Yes. |
The following types are not provided:
-
mem_fun_t
-
mem_fun1_t
-
mem_fun1_ref_t
-
mem_fun_ref_t
|
Not applicable. |
| <iostream> |
Yes. |
Not templatized and the following headers are not provided:
-
<fstream>
-
<iostream>
-
<istream>
-
<ostream>
-
<streambuf>
-
<sstream>
-
<iomanip>
-
<ios>
-
<iosfwd>
|
Not applicable. |
| <iterator> |
Yes. |
iterator template is not provided. |
Not applicable. |
| <locale > |
Yes. |
Not provided. |
Not applicable. |
| printf(3) formats |
Not applicable. |
Not applicable. |
%ls and %lc are not provided |
| <utility> |
Yes. |
rel_ops namespace is not supported. |
Not applicable. |
| <valarray> |
Yes. |
Not provided. |
Not applicable. |
| wide character support |
Not applicable. |
Not applicable. |
The following functions are not provided:
- btowc
- fwide
- fwprintf
- fwscanf
- mbrlen
- mbrtowc
- mbsinit
- mbsrtowcs
- swprintf
- swscanf
- towctrans
- vfwprintf
- vswprintf
- vwprintf
- wcrtomb
- wcsrtombs
- wcsstr
- wctob
- wctrans
- wmemchr
- wmemcmp
- wmemcpy
- wmemmove
- wmemset
- wprintf
- wscanf
|