Dela via


Support For C++11 Features (Modern C++)

This article describes C++11 features in Visual C++.

In This Article

  • C++11 Feature List

    • Core Language Feature Table

    • Core Language Feature Table: Concurrency

    • Core Language Feature Table: C99

  • Guide To Feature Tables

    • Rvalue References

    • Lambdas

    • decltype

    • Strongly Typed/Forward Declared enums

    • Alignment

    • Standard-Layout and Trivial Types

    • Defaulted and deleted functions

    • override and final

    • Atomics, and more

    • C99 __func__ and preprocessor rules

  • Standard Library features

C++11 Feature List

Visual C++ in Visual Studio 2010 implemented many features in the C++11 core language specification, and Visual C++ in Visual Studio 2012 added more of them. Visual C++ in Visual Studio 2013 expands this coverage even further, and also supports some C++14 Library features. The following table lists C++11 core language features and their implementation status in Visual C++ in Visual Studio 2010, Visual C++ in Visual Studio 2012, and Visual C++ in Visual Studio 2013.

C++11 Core Language Features Table

C++11 Core Language Features

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Rvalue references v0.1, v1.0, v2.0, v2.1, v3.0

v2.0

v2.1*

v2.1*

ref-qualifiers

No

No

No

Non-static data member initializers

No

No

Yes

Variadic templates v0.9, v1.0

No

No

Yes

Initializer lists

No

No

Yes

static_assert

Yes

Yes

Yes

auto v0.9, v1.0

v1.0

v1.0

v1.0

Trailing return types

Yes

Yes

Yes

Lambdas v0.9, v1.0, v1.1

v1.0

v1.1

v1.1

decltype v1.0, v1.1

v1.0

v1.1**

v1.1

Right angle brackets

Yes

Yes

Yes

Default template arguments for function templates

No

No

Yes

Expression SFINAE

No

No

No

Alias templates

No

No

Yes

Extern templates

Yes

Yes

Yes

nullptr

Yes

Yes

Yes

Strongly typed enums

Partial

Yes

Yes

Forward declared enums

No

Yes

Yes

Attributes

No

No

No

constexpr

No

No

No

Alignment

TR1

Partial

Partial

Delegating constructors

No

No

Yes

Inheriting constructors

No

No

No

Explicit conversion operators

No

No

Yes

char16_t/char32_t

No

No

No

Unicode string literals

No

No

No

Raw string literals

No

No

Yes

Universal character names in literals

No

No

No

User-defined literals

No

No

No

Standard-layout and trivial types

No

Yes

Yes

Defaulted and deleted functions

No

No

Yes*

Extended friend declarations

Yes

Yes

Yes

Extended sizeof

No

No

No

Inline namespaces

No

No

No

Unrestricted unions

No

No

No

Local and unnamed types as template arguments

Yes

Yes

Yes

Range-based for-loop

No

Yes

Yes

override and final v0.8, v0.9, v1.0

Partial

Yes

Yes

Minimal GC support

Yes

Yes

Yes

noexcept

No

No

No

[go to top]

C++11 Core Language Features Table: Concurrency

C++11 Core Language Features: Concurrency

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Reworded sequence points

N/A

N/A

N/A

Atomics

No

Yes

Yes

Strong compare and exchange

No

Yes

Yes

Bidirectional fences

No

Yes

Yes

Memory model

N/A

N/A

N/A

Data-dependency ordering

No

Yes

Yes

Data-dependency ordering: function annotation

No

No

No

exception_ptr

Yes

Yes

Yes

quick_exit

No

No

No

Atomics in signal handlers

No

No

No

Thread-local storage

Partial

Partial

Partial

Magic statics

No

No

No

[go to top]

C++11 Core Language Features: C99

C++11 Core Language Features: C99

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

__func__

Partial

Partial

Partial

C99 preprocessor

Partial

Partial

Partial

long long

Yes

Yes

Yes

Extended integer types

N/A

N/A

N/A

[go to top]

Guide to the Feature Tables

Rvalue References

Note

The version designations (v0.1, v1.0, v2.0, v2.1, v3.0) in the following descriptions are invented just to show the evolution of C++11. The standard itself does not use them.

N1610 "Clarification of Initialization of Class Objects by rvalues" was an early attempt to enable move semantics without rvalue references. For the sake of this discussion, let’s call it "rvalue references v0.1". It was superseded by "rvalue references v1.0." "Rvalue references v2.0", which is what the work in Visual C++ in Visual Studio 2010 was based on, prohibits rvalue references from binding to lvalues and thereby fixes a major safety problem. "Rvalue references v2.1" refines this rule. Consider vector<string>::push_back(), which has the overloads push_back(const string&) and push_back(string&&), and the call v.push_back("strval"). The expression "strval" is a string literal, and is an lvalue. (Other literals—for example, the integer 1729—are rvalues, but string literals are special because they are arrays.) The "rvalue references v2.0" rules said that string&& cannot bind to "strval" because "strval" is an lvalue and therefore, push_back(const string&) is the only viable overload. This would create a temporary std::string, copy it into the vector, and then destroy the temporary std::string, which wasn’t very efficient. The "rvalue references v2.1" rules recognize that binding string&& to "strval" would create a temporary std::string, and that temporary is an rvalue. Therefore, both push_back(const string&) and push_back(string&&) are viable, and push_back(string&&) is preferred. A temporary std::string is constructed, and then moved into the vector. This is more efficient.

"Rvalue references v3.0" adds new rules to automatically generate move constructors and move assignment operators under certain conditions. However, this is not implemented in Visual C++ in Visual Studio 2013, due to time and resource constraints.

[go to top]

Lambdas

After lambda functions were voted into the Working Paper (version "0.9") and mutable lambdas were added (version "1.0"), the Standardization Committee overhauled the wording. This produced lambdas version "1.1", which is now fully supported. The lambdas v1.1 wording clarifies what should occur in corner cases like referring to static members or nested lambdas. This fixes problems that are triggered by complex lambdas. Additionally, stateless lambdas are now convertible to function pointers. This is not in the N2927 wording, but it is counted as part of lambdas v1.1 anyway. C++115.1.2 [expr.prim.lambda]/6 has this description: "The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator." (The Visual C++ in Visual Studio 2012 implementation is even better than that, because it makes stateless lambdas convertible to function pointers that have arbitrary calling conventions. This is important when you are using APIs that expect things like __stdcall function pointers.)

[go to top]

decltype

After decltype was voted into the Working Paper (version 1.0), it received a small but important fix at the last minute (version 1.1). This is of great interest to programmers who work on the STL and Boost.

[go to top]

Strongly Typed/Forward Declared enums

Strongly typed enums were partially supported in Visual C++ in Visual Studio 2010 (specifically, the part about explicitly specified underlying types). These are now fully implemented in Visual Studio, and the C++11 semantics for forward declared enums are also fully implemented.

[go to top]

Alignment

The Core Language keywords alignas/alignof from the alignment proposal that was voted into the Working Paper are not implemented. Visual C++ in Visual Studio 2010 had aligned_storage from TR1. Visual C++ in Visual Studio 2012 added aligned_union and std::align() to the Standard Library and significant issues were fixed in Visual C++ in Visual Studio 2013.

[go to top]

Standard-Layout and Trivial Types

The exposed changes from N2342 "POD's Revisited; Resolving Core Issue 568 (Revision 5)" are the additions of is_trivial and is_standard_layout to the Standard Template Library's <type_traits>. (N2342 reworked a lot of the Core Language wording, but no compiler changes were required.) These type traits were available in Visual C++ in Visual Studio 2010, but they just duplicated is_pod. Therefore, the table earlier in this document said "No" support. They are now powered by compiler hooks that are designed to give accurate answers.

The STL's common_type<> received a much-needed fix in Visual C++ in Visual Studio 2013. The C++11 specification for common_type<> had unexpected and undesired consequences; in particular, it makes common_type<int, int>::type return int&&. Therefore, Visual C++ in Visual Studio 2013 implements the Proposed Resolution for Library Working Group issue 2141, which makes common_type<int, int>::type return int.

As a side-effect of this change, the identity case no longer works (common_type<T> does not always result in type T). This complies with the Proposed Resolution, but it breaks any code that relied on the previous behavior.

If you require an identity type trait, don't use the non-standard std::identity that's defined in <type_traits> because it won't work for <void>. Instead, implement your own identity type trait to suit your needs. Here's an example:

template <typename T> struct Identity {
    typedef T type;
};

Note

For other breaking changes, see Breaking Changes in Visual C++.

[go to top]

Defaulted and Deleted Functions

These are now supported, but with this exception: For defaulted functions, the use of =default to request member-wise move constructors and move assignment operators is not supported. The copies and moves don't interact precisely like the Standard says they should—for example, deletion of moves is specified to also suppress copies, but Visual C++ in Visual Studio 2013 does not.

For information about how to use defaulted and deleted functions, see C++ Function Definitions.

[go to top]

override and final

This went through a short but complicated evolution. Originally, in version 0.8, there were [[override]], [[hiding]], and [[base_check]] attributes. Then in version 0.9, the attributes were eliminated and replaced with contextual keywords. Finally, in version 1.0, they were reduced to "final" on classes, and "override" and "final" on functions. This makes it an Ascended Extension because Visual C++ in Visual Studio 2010 already supported this "override" syntax on functions, and had semantics reasonably close to those in C++11. "final" was also supported, but under the different spelling "sealed". The Standard spelling and semantics of "override" and "final" are now completely supported. For more information, see override Specifier and final Specifier.

[go to top]

Atomics, and More

Atomics, strong compare and exchange, bidirectional fences, and data-dependency ordering specify Standard Library machinery, which are now implemented.

Related STL headers:<atomic>, <chrono>, <condition_variable>, <future>, <mutex>, <ratio>, <scoped_allocator>, and <thread>.

[go to top]

C99 __func__ and Preprocessor Rules

The table Core Language Feature Table: C99 lists "Partial" implementation for two items. For the pre-defined identifier __func__, "Partial" is listed because support is provided for the non-Standard extensions __FUNCDNAME__, __FUNCSIG__, and __FUNCTION__. For more information, see Predefined Macros. For C99 preprocessor rules, "Partial" is listed because variadic macros are supported. For more information, see Variadic Macros.

[go to top]

Standard Library Features

That covers the Core Language. As for the C++11 Standard Library, we don't have a pretty comparison table of features, but Visual C++ in Visual Studio 2012 implemented it, with two exceptions. First, when a library feature depended on functionality that was missing in the compiler, it was either simulated—for example, simulated variadic templates for make_shared<T>()—or it wasn't implemented. (There were only a few cases—most notably, <initializer_list>—which are now fully implemented in Visual C++ in Visual Studio 2013.) With very few exceptions, C99 has been implemented in Visual C++ in Visual Studio 2013 and C++ wrapper headers provided. For more information, see C99 library support in Visual Studio 2013.

Here's a partial list of the changes in Visual C++ in Visual Studio 2012 and Visual C++ in Visual Studio 2013:

Emplacement: As required by C++11, emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() are implemented in all containers for "arbitrary" numbers of arguments (see the "Simulated variadics" section). For example, vector<T> has "template <typename... Args> void emplace_back(Args&&... args)", which directly constructs an element of type T at the back of the vector from an arbitrary number of arbitrary arguments, perfectly forwarded. This can be more efficient than push_back(T&&), which would involve an extra move construction and destruction.

Variadics: Visual C++ in Visual Studio 2012 had a scheme for simulating variadic templates. In Visual C++ in Visual Studio 2013, the simulations are gone and variadics are fully implemented. If your code relies on the old simulated variadics behavior, you have to fix it. However, the switch to real variadic templates has improved compile times and reduced compiler memory consumption.

Explicit conversion operators: In the Core Language, explicit conversion operators are a general feature—for example, you can have explicit operator MyClass(). However, the Standard Library currently uses only one form: explicit operator bool(), which makes classes safely Boolean-testable. (Plain "operator bool()" is notoriously dangerous.) Previously, Visual C++ simulated explicit operator bool() with operator pointer-to-member(), which led to various headaches and slight inefficiencies. Now, this "fake bool" workaround is completely removed.

**Randomness:**uniform_int_distribution is now perfectly unbiased, and shuffle() is implemented in <algorithm>, which directly accepts Uniform Random Number Generators like mersenne_twister.

Resistance to overloaded address-of operators: C++98/03 prohibited an element of an STL container from overloading its address-of operator. This is what classes like CComPtr do, so that helper classes like CAdapt were required to shield the STL from such overloads. During the development of Visual C++ in Visual Studio 2010, STL changes made it reject overloaded address-of operators in even more situations. C++11 changed the requirements to make overloaded address-of operators acceptable. C++11, and Visual C++ in Visual Studio 2010, provide the helper function std::addressof(), which can get the true address of an object regardless of operator overloading. Before Visual C++ in Visual Studio 2010 was released, we attempted to replace occurrences of "&elem" with "std::addressof(elem)", which is appropriately resistant. Visual C++ in Visual Studio 2012 went further, so that classes that overload their address-of operator should be usable throughout the STL.

Visual C++ in Visual Studio 2012 went beyond C++11 in several ways:

SCARY iterators: As permitted but not required by the C++11 Standard, SCARY iterators have been implemented, as described by N2911 "Minimizing Dependencies within Generic Classes for Faster and Smaller Programs" and N2980 "SCARY Iterator Assignment and Initialization, Revision 1".

Filesystem: The <filesystem> header from the TR2 proposal has been added. It offers recursive_directory_iterator and other interesting features. Before work on TR2 was frozen because C++0x was running very late and was changing to C++11, the 2006 proposal was derived from Boost.Filesystem V2. It later evolved into Boost.Filesystem V3, but that's not implemented in Visual C++ in Visual Studio 2012.

And a major optimization! All of our containers are now optimally small given their current representations. This refers to the container objects themselves, not to their pointed-to contents. For example, std::vector contains three raw pointers. In Visual C++ in Visual Studio 2010, x86 release mode, std::vector was 16 bytes. In Visual C++ in Visual Studio 2012, it is 12 bytes, which is optimally small. This is a big deal—if you have 100,000 vectors in your program, Visual C++ in Visual Studio 2012 saves you 400,000 bytes. Decreased memory usage saves both space and time.

This was achieved by avoiding the storage of empty allocators and comparators, because std::allocator and std::less are stateless. (These optimizations are enabled for custom allocators/comparators too, as long as they are stateless. Obviously, storage of stateful allocators/comparators cannot be avoided, but those are very rare.)

Visual C++ in Visual Studio 2013 goes even further beyond C++11 to implement some key C++14 library features:

  • "Transparent operator functors" less<>, greater<>, plus<>, multiplies<>, and so on.

  • make_unique<T>(args...) and make_unique<T[]>(n)

  • cbegin()/cend(), rbegin()/rend(), and crbegin()/crend() non-member functions.

[go to top]

See Also

Reference

Lambda Expressions in C++

Range-based for Statement (C++)

Concepts

What's New for Visual C++ in Visual Studio 2013

Breaking Changes in Visual C++

Other Resources

Welcome Back to C++ (Modern C++)

C++ Language Reference

C++ Standard Library Reference

Visual C++ Team Blog