This subclause lists the differences between C++ and ISO C++ 2014 (ISO/IEC 14882:2014, Programming Languages — C++), by the chapters of this document.
[lex.phases]
Change: Removal of trigraph support as a required feature.
Rationale: Prevents accidental uses of trigraphs in non-raw string literals and comments.
Effect on original feature:
Valid C++ 2014 code that uses trigraphs may not be valid or may have different
semantics in this International Standard. Implementations may choose to
translate trigraphs as specified in C++ 2014 if they appear outside of a raw
string literal, as part of the implementation-defined mapping from physical source file characters to
the basic source character set.
[lex.ppnumber]
Change: pp-number can contain p sign and
P sign.
Rationale: Necessary to enable hexadecimal floating literals.
Effect on original feature:
Valid C++ 2014 code may fail to compile or produce different results in
this International Standard. Specifically, character sequences like 0p+0
and 0e1_p+0 are three separate tokens each in C++ 2014, but one single token
in this International Standard.
#define F(a) b ## a
int b0p = F(0p+0); // ill-formed; equivalent to “int b0p = b0p + 0;” in C++ 2014
[expr.post.incr], [expr.pre.incr]
Change:
Remove increment operator with bool operand.
Rationale: Obsolete feature with occasionally surprising semantics.
Effect on original feature: A valid C++ 2014 expression utilizing the increment operator on
a bool lvalue is ill-formed in this International Standard.
Note that this might occur when the lvalue has a type given by a template
parameter.
[expr.new], [expr.delete]
Change: Dynamic allocation mechanism for over-aligned types.
Rationale: Simplify use of over-aligned types.
Effect on original feature: In C++ 2014 code that uses a new-expression
to allocate an object with an over-aligned class type,
where that class has no allocation functions of its own,
::operator new(std::size_t)
is used to allocate the memory.
In this International Standard,
::operator new(std::size_t, std::align_val_t)
is used instead.
[dcl.stc]
Change: Removal of register storage-class-specifier.
Rationale: Enable repurposing of deprecated keyword in future revisions of this International Standard.
Effect on original feature:
A valid C++ 2014 declaration utilizing the register
storage-class-specifier is ill-formed in this International Standard.
The specifier can simply be removed to retain the original meaning.
[dcl.spec.auto]
Change: auto deduction from braced-init-list.
Rationale: More intuitive deduction behavior.
Effect on original feature:
Valid C++ 2014 code may fail to compile or may change meaning
in this International Standard. For example:
auto x1{1}; // was std::initializer_list<int>, now int auto x2{1, 2}; // was std::initializer_list<int>, now ill-formed
[dcl.fct]
Change: Make exception specifications be part of the type system.
Rationale: Improve type-safety.
Effect on original feature:
Valid C++ 2014 code may fail to compile or change meaning in this
International Standard:
void g1() noexcept;
void g2();
template<class T> int f(T *, T *);
int x = f(g1, g2); // ill-formed; previously well-formed
[dcl.init.aggr]
Change: Definition of an aggregate is extended
to apply to user-defined types with base classes.
Rationale: To increase convenience of aggregate initialization.
Effect on original feature:
Valid C++ 2014 code may fail to compile or produce different results in this
International Standard; initialization from an empty initializer list will
perform aggregate initialization instead of invoking a default constructor
for the affected types:
struct derived; struct base { friend struct derived; private: base(); }; struct derived : base {}; derived d1{}; // Error. The code was well-formed before. derived d2; // still OK
[class.inhctor.init]
Change:
Inheriting a constructor no longer injects a constructor into the derived class.
Rationale:
Better interaction with other language features.
Effect on original feature:
Valid C++ 2014 code that uses inheriting constructors may not be valid
or may have different semantics. A using-declaration
that names a constructor now makes the corresponding base class constructors
visible to initializations of the derived class
rather than declaring additional derived class constructors.
struct A { template<typename T> A(T, typename T::type = 0); A(int); }; struct B : A { using A::A; B(int); }; B b(42L); // now calls B(int), used to call B<long>(long), // which called A(int) due to substitution failure // in A<long>(long).
[temp.deduct.type]
Change: Allowance to deduce from the type of a non-type template argument.
Rationale: In combination with the ability to declare
non-type template arguments with placeholder types,
allows partial specializations to decompose
from the type deduced for the non-type template argument.
Effect on original feature: Valid C++ 2014 code may fail to compile
or produce different results in this International Standard:
template <int N> struct A;
template <typename T, T N> int foo(A<N> *) = delete;
void foo(void *);
void bar(A<0> *p) {
foo(p); // ill-formed; previously well-formed
}
[except.spec]
Change: Remove dynamic exception specifications.
Rationale: Dynamic exception specifications were a deprecated feature
that was complex and brittle in use.
They interacted badly with the type system,
which became a more significant issue in this International Standard
where (non-dynamic) exception specifications are part of the function type.
Effect on original feature:
A valid C++ 2014 function declaration,
member function declaration,
function pointer declaration,
or function reference declaration,
if it has a potentially throwing dynamic exception specification,
will be rejected as ill-formed in this International Standard.
Violating a non-throwing dynamic exception specification
will call terminate
rather than unexpected
and might not perform stack unwinding prior to such a call.
[namespace.future]
Change: New reserved namespaces.
Rationale: Reserve namespaces for future revisions of the standard library
that might otherwise be incompatible with existing programs.
Effect on original feature:
The global namespaces std
followed by an arbitrary sequence of digits
is reserved for future standardization.
Valid C++ 2014 code that uses such a top-level namespace,
e.g., std2, may be invalid in this International Standard.
[func.wrap]
Change: Constructors taking allocators removed.
Rationale: No implementation consensus.
Effect on original feature:
Valid C++ 2014 code may fail to compile or may change meaning in this
International Standard. Specifically, constructing a std::function with
an allocator is ill-formed and uses-allocator construction will not pass an
allocator to std::function constructors in this International Standard.
[util.smartptr.shared]
Change: Different constraint on conversions from unique_ptr.
Rationale: Adding array support to shared_ptr,
via the syntax shared_ptr<T[]> and shared_ptr<T[N]>.
Effect on original feature:
Valid C++ 2014code may fail to compile or may change meaning in this
International Standard.
For example:
#include <memory>
std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int> ptr(std::move(arr)); // error: int(*)[] is not compatible with int*
[basic.string]
Change: Non-const .data() member added.
Rationale: The lack of a non-const .data()
differed from the similar member of std::vector.
This change regularizes behavior for this International Standard.
Effect on original feature:
Overloaded functions which have differing code paths
for char* and const char* arguments
will execute differently
when called with a non-const string's .data() member
in this International Standard.
int f(char *) = delete;
int f(const char *);
string s;
int x = f(s.data()); // ill-formed; previously well-formed
[associative.reqmts]
Change: Requirements change:
Rationale: Increase portability, clarification of associative container requirements.
Effect on original feature:
Valid C++ 2014 code that attempts to use associative containers
having a comparison object with non-const function call operator
may fail to compile in this International Standard:
#include <set> struct compare { bool operator()(int a, int b) { return a < b; } }; int main() { const std::set<int, compare> s; s.find(0); }
Change:
The class templates
auto_ptr,
unary_function, and
binary_function,
the function templates
random_shuffle,
and the function templates (and their return types)
ptr_fun,
mem_fun,
mem_fun_ref,
bind1st, and
bind2nd
are not defined.
Rationale: Superseded by new features.
Effect on original feature: Valid C++ 2014 code that uses these class templates
and function templates may fail to compile in this International Standard.
Change:
Remove old iostreams members [depr.ios.members].
Rationale: Redundant feature for compatibility with pre-standard code
has served its time.
Effect on original feature: A valid C++ 2014 program using these identifiers
may be ill-formed in this International Standard.