资讯详情

Visual C++ 新增功能(2003 - 2015)

本页包括从 Visual Studio 2003 到 Visual Studio 2015 的所有 Visual C 版本的新功能页面。从早期版本提供这些信息的目的是方便用户 Visual Studio 进行升级。

Visual Studio 2015 中 C 的新增功能

在 Visual Studio 2015 在更高的版本中,编译符合性的持续改进有时会改变编译理解现有源代码的方式。当这种情况发生时,在生成过程中可能会遇到新的或不同的错误,甚至以前生成的代码也可能会出现行为差异。

幸运的是,这些差异对大部分源代码没有影响或影响极小,而且需要更改源代码或进行其他更改以解决这些差异时,修补程序通常小型且简单。我们列出了许多可接受的源代码示例(之前)及其修复程序(之后),现在可能需要更改。

虽然这些差异可能会影响源代码或其他生成项目,但它们不会影响 Visual C 版本更新之间的二进制文件兼容性。重大变更是严重性较高的变更,可能会影响二进制文件的兼容性,但这种二进制文件的兼容性中断只发生在 Visual C 主版本之间。例如,在 Visual C 2013 和 Visual C 2015 之间。有关 Visual C 2013 和 Visual C 2015 请参考重大变更的详细信息Visual C 改变历史记录(2003) - 2015)。

  • Visual Studio 2015 一致性改进

  • Visual Studio 2015 Update 1 提高符合性

  • Visual Studio 2015 Update 2 一致性改进

  • Visual Studio 2015 Update 3 提高符合性

Visual Studio 2015 提高符合性

Visual Studio 2015 Update 1 中的一致性改进

  • 早期版本的编译器允许派生类调用 间接派生 private virtual 基类的成员函数。 这种旧行为不正确,也不符合 C++ 标准。 编译器不再接受这种方式编写的代码,因此会发出编译器错误 C2280。

      error C2280: 'void *S3::__delDtor(unsigned int)': attempting to reference a deleted function
    

    示例(之前)

      class base
      {
      protected:
          base();
          ~base();
      };
    
      class middle: private virtual base {};class top: public virtual middle {};
    
      void destroy(top *p)
      {
          delete p;  //
      }
    

    示例(之后)

      class base;  // as above
    
      class middle: protected virtual base {};
      class top: public virtual middle {};
    
      void destroy(top *p)
      {
          delete p;
      }
    

    - 或 -

      class base;  // as above
    
      class middle: private virtual base {};
      class top: public virtual middle, private virtual bottom {};
    
      void destroy(top *p)
      {
          delete p;
      }
    
  • 早期版本的编译器允许非成员 new 运算符和非成员 delete 运算符声明为静态,并在全局命名空间之外的命名空间中声明。 这种旧行为会导致程序无法调用程序员所需的  或  运算符实现,从而导致无提示的运行时行为。 编译器不再接受这种方式编写的代码,因此会发出编译器错误 C2323。

      error C2323: 'operator new': non-member operator new or delete functions may not be declared static or in a namespace other than the global namespace.
    

    示例(之前)

      static inline void * __cdecl operator new(size_t cb, const std::nothrow_t&)  // error C2323
    

    示例(之后)

      void * __cdecl operator new(size_t cb, const std::nothrow_t&)  // removed 'static inline'
    

    此外,尽管编译器不能进行具体诊断,但内联运算符 new 会被视为格式不正确。

  •  早期版本的编译器允许以无提示忽略的方式对非类类型调用“operator type()”。 这种旧行为会导致无提示代码生成错误风险,从而导致不可预知的运行时行为。 编译器不再接受这种方式编写的代码,因此会发出编译器错误 C2228。

      error C2228: left of '.operator type' must have class/struct/union
    

    示例(之前)

      typedef int index_t;
    
      void bounds_check(index_t index);
    
      void login(int column)
      {
          bounds_check(column.operator index_t());  // error C2228
      }
    

    示例(之后)

      typedef int index_t;
    
      void bounds_check(index_t index);
    
      void login(int column)
      {
           bounds_check(column);  // removed cast to 'index_t', 'index_t' is an alias of 'int'
      }
    
  •  早期版本的编译器允许  在详细的类型说明符中使用; 以这种方式编写的代码在语义上不正确。 编译器不再接受这种方式编写的代码,因此会发出编译器错误 C3406。

      error C3406: 'typename' cannot be used in an elaborated type specifier
    

    示例(之前)

      template <typename class T>
      class container;
    

    示例(之后)

      template <class T>  // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case
      class container;
    
  •  早期版本的编译器不支持对初始值设定项列表中的数组进行类型推断。 编译器现在支持这种形式的类型推断,因此调用使用初始值设定项列表的函数模板现在可能会不明确,或者选择一个与以前版本的编译器不同的重载。 要解决这些问题,程序现在必须显式指定程序员所需的重载。

    当这一新行为导致重载解决方法要考虑与以往候选一样好的其他候选时,调用变得不明确,编译器会发出编译器错误 C2668。

      error C2668: 'function' : ambiguous call to overloaded function.
    

    示例 1: 对重载函数的调用不明确(之前)

      // In previous versions of the compiler, code written in this way would unambiguously call f(int, Args...)
      template <typename... Args>
      void f(int, Args...);  //
    
      template <int N, typename... Args>
      void f(const int (&)[N], Args...);
    
      int main()
      {
          // The compiler now considers this call ambiguous, and issues a compiler error
          f({3});  error C2668: 'f' ambiguous call to overloaded function
      }
    

    示例 1: 对重载函数的调用不明确(之后)

      template <typename... Args>
      void f(int, Args...);  //
    
      template <int N, typename... Args>
      void f(const int (&)[N], Args...);
    
      int main()
      {
          // To call f(int, Args...) when there is just one expression in the initializer list, remove the braces from it.
          f(3);
      }
    

    这一新行为会导致重载解决方法要考虑比以往候选更适合的其他候选时,调用将明确地解析为新候选,导致程序行为的更改可能与程序员的需要有所不同。

    示例 2:重载解决方法的更改(之前)

      // In previous versions of the compiler, code written in this way would unambiguously call f(S, Args...)
      struct S
      {
          int i;
          int j;
      };
    
      template <typename... Args>
      void f(S, Args...);
    
      template <int N, typename... Args>
      void f(const int *&)[N], Args...);
    
      int main()
      {
          // The compiler now resolves this call to f(const int (&)[N], Args...) instead
          f({1, 2});
      }
    

    示例 2:重载解决方法的更改(之后)

      struct S;  // as before
    
      template <typename... Args>
      void f(S, Args...);
    
      template <int N, typename... Args>
      void f(const int *&)[N], Args...);
    
      int main()
      {
          // To call f(S, Args...), perform an explicit cast to S on the initializer list.
          f(S{1, 2});
      }
    
  • 以前版本的编译器删除了以前存在的与语句相关的警告  ; 这些警告现在已还原。 编译器现在将发出还原的警告,并且现在会在包含有问题用例的行中发出与特定用例(包括默认情况下)相关的警告,而不是在 switch 语句的最后一行发出。 因此,现在发出这些警告的行与过去不同,按照需要使用 #pragma warning(disable:####) 可不再禁止显示以前禁止显示的警告。 要按照需要禁止显示这些警告,可能需要将 #pragma warning(disable:####) 指令移到第一个可能有问题的用例上面的行。 以下是还原的警告。

      warning C4060: switch statement contains no 'case' or 'default' labels
    
      warning C4061: enumerator 'bit1' in switch of enum 'flags' is not explicitly handled by a case label
    
      warning C4062: enumerator 'bit1' in switch of enum 'flags' is not handled
    
      warning C4063: case 'bit32' is not a valid value for switch of enum 'flags'
    
      warning C4064: switch of incomplete enum 'flags'
    
      warning C4065: switch statement contains 'default' but no 'case' labels
    
      warning C4808: case 'value' is not a valid value for switch condition of type 'bool'
    
      Warning C4809: switch statement has redundant 'default' label; all possible 'case' labels are given
    

    C4063 示例(之前)

      class settings
      {
      public:
          enum flags
          {
              bit0 = 0x1,
              bit1 = 0x2,
              ...
          };
          ...
      };
    
      int main()
      {
          auto val = settings::bit1;
    
          switch (val)
          {
          case settings::bit0:
              break;
    
          case settings::bit1:
              break;
    
          case settings::bit0 | settings::bit1:  // warning C4063
              break;
          }
      };
    

    C4063 示例(之后)

      class settings {...};  // as above
    
      int main()
      {
          // since C++11, use std::underlying_type to determine the underlying type of an enum
          typedef std::underlying_type<settings::flags>::type flags_t;
    
          auto val = settings::bit1;
    
          switch (static_cast<flags_t>(val))
          {
          case settings::bit0:
              break;
    
          case settings::bit1:
              break;
    
          case settings::bit0 | settings::bit1:  // ok
              break;
          }
      };
    

    在其文档中提供了其他还原警告的示例。

  • #include:在路径名中使用父目录说明符“..”(只影响 /Wall /WX

    早期版本的编译器没有检测到使用父目录说明符“..” (在 #include 指令的路径名中)。 以这种方式编写的代码通常用于包含因不正确使用项目相对路径而留在项目外的标头。 这一旧行为会引发风险,导致编译程序时包含了程序员不需要的源文件来,或这些相对路径不能移植到其他生成环境中。 编译器现在会检测以这种方式编写的代码并通知程序员,并发出可选编译器警告 C4464(如果已启用)。

      warning C4464: relative include path contains '..'
    

    示例(之前)

      #include "..\headers\C4426.h"  // emits warning C4464
    

    示例(之后)

      #include "C4426.h"  // add absolute path to 'headers\' to your project's include directories
    

    此外,虽然编译器并不会进行具体诊断,但建议不应将父目录说明符“..”用于指定项目的包含目录。

  • #pragma optimize() 超出标头文件的末尾(只影响 /Wall /WX

    早期版本的编译器无法检测到对转义翻译单元中包含的标头文件的优化标志设置的更改。 编译器现在会检测以这种方式编写的代码并通知程序员,并在有问题的 #include的位置发出可选编译器警告 C4426(如果已启用)。 只有更改与编译器命令行参数设置的优化标志发生冲突时,才发出此警告。

      warning C4426: optimization flags changed after including header, may be due to #pragma optimize()
    

    示例(之前)

      // C4426.h
      #pragma optimize("g", off)
      ...
      // C4426.h ends
    
      // C4426.cpp
      #include "C4426.h"  // warning C4426
    

    示例(之后)

      // C4426.h
      #pragma optimize("g", off)
      ...
      #pragma optimize("", on)  // restores optimization flags set via command-line arguments
      // C4426.h ends
    
      // C4426.cpp
      #include "C4426.h"
    
  • #pragma warning(push) 和 #pragma warning(pop)(只影响 /Wall /WX

    早期版本的编译器无法检测到不同源文件中与 #pragma warning(pop) 状态更改配对的 #pragma warning(push) 状态更改,这并不是我们所预期的。 这种旧行为会引发风险,导致程序编译时会启用一组程序员不希望出现的警告,可能会导致无提示的运行时行为错误。 编译器现在能够检测以这种方式编写的代码并通知程序员,并在匹配 #pragma warning(pop) 位置发出可选编译器警告 C5031(如果已启用)。 此警告中有一个注释,其中引用了相应 #pragma warning(push) 的位置。

      warning C5031: #pragma warning(pop): likely mismatch, popping warning state pushed in different file
    

    示例(之前)

      // C5031_part1.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      // C5031_part1.h ends without #pragma warning(pop)
    
      // C5031_part2.h
      ...
      #pragma warning(pop)  // pops a warning state not pushed in this source file
      ...
      // C5031_part1.h ends
    
      // C5031.cpp
      #include "C5031_part1.h" // leaves #pragma warning(push) 'dangling'
      ...
      #include "C5031_part2.h" // matches 'dangling' #pragma warning(push), resulting in warning C5031
      ...
    

    示例(之后)

      // C5031_part1.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      #pragma warning(pop)  // pops the warning state pushed in this source file
      // C5031_part1.h ends without #pragma warning(pop)
    
      // C5031_part2.h
      #pragma warning(push)  // pushes the warning state pushed in this source file
      #pragma warning(disable:####)
      ...
      #pragma warning(pop)
      // C5031_part1.h ends
    
      // C5031.cpp
      #include "C5031_part1.h" // #pragma warning state changes are self-contained and independent of other source files or their #include order.
      ...
      #include "C5031_part2.h"
      ...
    

    虽然不常见,但是有时会故意以这种方式编写代码。 以这种方式编写的代码对于 #include 顺序的更改比较敏感;如果可能,我们建议源代码文件以自包含的方式管理警告状态。

  • #pragma warning(push) 不匹配(只影响 /Wall /WX

    早期版本的编译器无法检测到翻译单元末尾出现的不匹配 #pragma warning(push) 状态更改。 而现在,编译器可检测按此方式编写的代码并通知程序员,还可在 #pragma warning(push) 不匹配的位置发出编译器警告 C5032(如已启用)。 只有翻译单元中没有任何编译错误时,才会发出此警告。

      warning C5032: detected #pragma warning(push) with no corresponding #pragma warning(pop)
    

    示例(之前)

      // C5032.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      // C5032.h ends without #pragma warning(pop)
    
      // C5032.cpp
      #include "C5032.h"
      ...
      // C5032.cpp ends -- the translation unit is completed without #pragma warning(pop), resulting in warning C5032 on line 1 of C5032.h
    

    示例(之后)

      // C5032.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      #pragma warning(pop) // matches #pragma warning (push) on line 1
      // C5032.h ends
    
      // C5032.cpp
      #include "C5032.h"
      ...
      // C5032.cpp ends -- the translation unit is completed without unmatched #pragma warning(push)
    
  • 早期版本的编译器无法有效跟踪 #pragma warning 状态更改,因而无法发出所有所需的警告。 这种行为会引发风险,导致在程序不希望的情况下有效禁止显示某些警告。 而现在,编译器可更加可靠地跟踪 #pragma warning 状态(尤其与模板内部的 #pragma warning 状态更改相关),并选择性发出新警告 C5031 和 C5032,目的是帮助程序员了解意外使用 #pragma warning(push) 和 #pragma warning(pop) 的情况。

    由于 #pragma warning 状态更改跟踪得到了改进,现在可能会发出之前误禁的警告或与之前误诊问题相关的警告。

  • 针对早期版本的编译器进行的 C++ 标准库的更改和内联函数调用能力改进可能会使编译器能够证明某些代码现在无法访问。 这一新行为可能导致新警告并更频繁地发出警告 C4720 实例。

      warning C4720: unreachable code
    

    在许多情况下,只有启用优化进行编译时,才会发出此警告,因为优化可能嵌入更多函数调用,消除冗余代码或者能够确定某些代码是否无法访问。 我们发现,C4720 的新实例在  块中经常发生,尤其是在使用 std:: find的情况下。

    示例(之前)

      try
      {
          auto iter = std::find(v.begin(), v.end(), 5);
      }
      catch(...)
      {
          do_something();  // ok
      }
    

    示例(之后)

      try
      {
          auto iter = std::find(v.begin(), v.end(), 5);
      }
      catch(...)
      {
          do_something();  // warning C4702: unreachable code
      }
    

Visual Studio 2015 Update 2 的符合性改进

Visual Studio 2015 Update 3 中的一致性改进

  • (标准库) 以前版本的 std::is_convertable type-trait 在其复制构造函数被删除或私有时,无法正确检测类类型的自我赋值。 现在, std::is_convertable<>::value  在应用于具有已删除或私有复制构造函数的类类型时,正确设置为。

    没有与此更改相关联的编译器诊断。

    示例

    C++复制

      #include <type_traits>
    
      class X1
      {
      public:
          X1(const X1&) = delete;
      };
    
      class X2
      {
      private:
          X2(const X2&);
      };
    
      static_assert(std::is_convertible<X1&, X1>::value, "BOOM");static_assert(std::is_convertible<X2&, X2>::value, "BOOM");
    

    在 Visual C++ 的以前版本中,此示例底部的静态断言通过,因为 std::is_convertable<>::value 错误地设置为  。 现在, std::is_convertable<>::value 正确设置为  ,导致静态断言失败。

  • 对于默认设置或已删除的日常复制和移动构造函数的访问说明符,早期版本的编译器在允许调用之前不进行检查。 这种旧行为不正确,也不符合 C++ 标准。 在某些情况下,这种旧行为会导致无提示代码生成错误风险,从而导致不可预知的运行时行为。 现在,编译器检查默认设置或已删除的日常复制和移动构造函数的访问说明符,以确定是否能调用它,如果不能,则发出编译器警告 C2248。

    Output复制

      error C2248: 'S::S' cannot access private member declared in class 'S'
    

    示例(之前)

    C++复制

      class S {
      public:
         S() = default;
      private:
          S(const S&) = default;
      };
    
      void f(S);  // pass S by value
    
      int main()
      {
          S s;
          f(s);  // error C2248, can't invoke private copy constructor
      }
    

    示例(之后)

    C++复制

      class S {
      public:
         S() = default;
      private:
          S(const S&) = default;
      };
    
      void f(const S&);  // pass S by reference
    
      int main()
      {
          S s;
          f(s);
      }
    
  • (默认开启等级 1 (/W1))

    以前版本的编译器支持属性化 ATL 代码。 由于下一阶段将删除从 Visual C++ 2008 开始的属性化 ATL 代码支持,所以已弃用属性化 ATL 代码。 编译器现将发出编译器警告 C4467 以帮助识别这类已弃用的代码。

    Output复制

      warning C4467: Usage of ATL attributes is deprecated
    

    若要在编译器删除支持之前继续使用属性化 ATL 代码,可以通过将 /Wv:18 或 /wd4467 命令行参数传递给编译器或在源代码中添加 #pragma warning(disable:4467) 来禁用此警告。

    示例 1(之前)

    C++复制

                [uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")]
      class A {};
    

    示例 1(之后)

    C++复制

      __declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) A {};
    

    有时需要创建 IDL 文件以避免使用已弃用的 ATL 属性,如以下示例代码所示

    示例 2(之前)

    C++复制

      [emitidl];
      [module(name="Foo")];
    
      [object, local, uuid("9e66a290-4365-11d2-a997-00c04fa37ddb")]
      __interface ICustom {
          HRESULT Custom([in] long l, [out, retval] long *pLong);
          [local] HRESULT CustomLocal([in] long l, [out, retval] long *pLong);
      };
    
      [coclass, appobject, uuid("9e66a294-4365-11d2-a997-00c04fa37ddb")]
      class CFoo : public ICustom
      {
          // ...
      };
    

    首先,创建 *.idl 文件;vc140.idl 生成的文件可用于获取包含接口和注释的 *.idl文件。

    然后,将 MIDL 步骤添加到生成中以确保生成 C++ 接口定义。

    示例 2 IDL(之后)

    C++复制

      import "docobj.idl";
    
      [
          object,local,uuid(9e66a290-4365-11d2-a997-00c04fa37ddb)
      ]
    
      interface ICustom : IUnknown {
          HRESULT  Custom([in] long l, [out,retval] long *pLong);
          [local] HRESULT  CustomLocal([in] long l, [out,retval] long *pLong);
      };
    
      [ version(1.0), uuid(29079a2c-5f3f-3325-99a1-3ec9c40988bb) ]
      library Foo
      {
          importlib("stdole2.tlb");
          importlib("olepro32.dll");
              [
                  version(1.0),
                  appobject,uuid(9e66a294-4365-11d2-a997-00c04fa37ddb)
              ]
    
          coclass CFoo {
              interface ICustom;
          };
      }
    

    然后,在实现文件中直接使用 ATL,如以下示例代码所示。

    示例 2 实现(之后)

    C++复制

      #include <idl.header.h>
      #include <atlbase.h>
    
      class ATL_NO_VTABLE CFooImpl :
          public ICustom,
          public ATL::CComObjectRootEx<CComMultiThreadModel>
      {
      public:
          BEGIN_COM_MAP(CFooImpl)
          COM_INTERFACE_ENTRY(ICustom)
          END_COM_MAP()
      };
    
  • (仅影响 /Wall /WX

    使用预编译标头 (PCH) 文件时,以前版本的编译器接受 -Yc 和 -Yu 编译之间的源文件中不匹配的 #include 指令。 编译器不再接受以这种方式编写的代码。 使用 PCH 文件时,编译器现将发出编译器警告 CC4598 以帮助识别不匹配的 #include 指令。

    Output复制

      warning C4598: 'b.h': included header file specified for Ycc.h at position 2 does not match Yuc.h at that position
    

    示例(之前):

    X.cpp (-Ycc.h)

    C++复制

      #include "a.h"
      #include "b.h"
      #include "c.h"
    

    Z.cpp (-Yuc.h)

    C++复制

      #include "b.h"
      #include "a.h"  // mismatched order relative to X.cpp
      #include "c.h"
    

    示例(之后)

    X.cpp (-Ycc.h)

    C++复制

      #include "a.h"
      #include "b.h"
      #include "c.h"
    

    Z.cpp (-Yuc.h)

    C++复制

      #include "a.h"
      #include "b.h" // matched order relative to X.cpp
      #include "c.h"
    
  • (仅影响 /Wall /WX

    使用预编译标头 (PCH) 文件时,对于 -Yc 和 -Yu 编译之间的编译器,以前版本的编译器接受不匹配的包含目录 (-I) 命令行参数。 编译器不再接受以这种方式编写的代码。 使用 PCH 文件时,编译器现将发出编译器警告 CC4599 以帮助识别不匹配的包含目录 (-I) 命令行参数。

    Output复制

      warning C4599: '-I..' : specified for Ycc.h at position 1 does not match Yuc.h at that position
    

    示例(之前)

    ms-dos复制

      cl /c /Wall /Ycc.h -I.. X.cpp
      cl /c /Wall /Yuc.h Z.cpp
    

    示例(之后)

    ms-dos复制

      cl /c /Wall /Ycc.h -I.. X.cpp
      cl /c /Wall /Yuc.h -I.. Z.cpp
    

Visual Studio 2013 中 C++ 的新增功能

改进的 ISO C/C++ 标准支持

编译器

MSVC 支持以下 ISO C++11 语言功能:

  • 函数模板的默认模板参数。
  • 委托构造函数
  • 显式转换运算符。
  • 初始值设定项列表和统一初始化。
  • 原始字符串文本。
  • 可变参数模板。
  • 别名模板。
  • 已删除的函数。
  • 非静态数据成员初始值设定项 (NSDMI)。
  • 默认的函数。 *
  • 支持以下 ISO C99 语言功能:
  • _Bool
  • 复合文本。
  • 指定的初始值设定项。
  • 组合带有代码的声明。
  • 字符串文本转换为可修改的值可通过使用新编译器选项 /Zc:strictStrings 禁用。 在 c + + 98 中,已弃用从字符串文本到  (和宽字符串) 文本的转换 wchar_t* 。 在 C++11 中,已将转换完全移除。 虽然编译器可以严格遵循该标准,但提供了 /Zc:strictStrings 选项,以便您控制转换。 默认情况下,该选项是关闭的。 注意,当您在调试模式下使用此选项,STL 将无法编译。
  • rvalue/lvalue 引用转换。 通过 rvalue 引用,C++11 可清晰地区分 lvalue 和 rvalue。 过去,在特定强制转换方案中,编译器不提供此功能。 已添加新编译器选项(/Zc:rvalueCast),以使编译器与 C++ 语言的工作文件相符(请参阅第 5.4 节 [expr.cast]/1)。 未指定选项时,该默认行为与 Visual Studio 2012 中的相同。

 备注

对于默认函数,不支持使用 =default 请求逐一移动成员的构造函数和移动赋值运算符。

C99 库

为下列标头中缺少的函数添加了声明和实现:math.h、ctype.h、wctype.h、stdio.h、stdlib.h 和 wchar.h。 同样添加的还有新标头 complex.h、stdbool.h、fenv.h 和 inttypes.h,以及这些新标头中声明的所有函数的实现。 新增了一些 C++ 包装器标头(ccomplex、cfenv、cinttypes 和 ctgmath)并更新了许多其他标头(ccomplex、cctype、clocale、cmath、cstdint、cstdio、cstring、cwchar 和 cwctype)。

标准模板库

支持 C++11 显式转换运算符、初始值设定项列表、范围枚举和 variadic 模板。 现在所有容器都支持 C++11 细化的元素要求。 支持这些 C++14 功能:

  • “透明运算符函子”less<>、greater<>、plus<>、multiplies<> 等等。
  • make_unique<T>(args...) 和 make_unique <T[]>(n)
  • cbegin()/cend()、rbegin()/rend() 和 crbegin()/crend() 非成员函数。
  • <atomic> 接收了许多性能增强功能。
  • <type_traits> 收到重大的稳定和代码修补程序。

重大更改

对 ISO C/C++ 标准的改进支持可能需要对现有代码进行更改,从而符合 C++11 并在 Visual Studio 2013 的 Visual C++ 中正确编译。

Visual C++ 库增强功能

  • 添加了 C++ REST SDK。 它具有 REST 服务的现代 C++ 实现。
  • C++ AMP 纹理支持已改进。 现在包括对 mipmap 和新采样模式的支持。
  • PPL 任务支持多个计划技术和异步调试。 采用新 API,可为常规结果和异常条件创建 PPL 任务。

C++ 应用程序性能

  • 自动向量化现在可以识别和优化更多 C++ 模式,加快代码运行速度。
  • ARM 平台和 Atom 微型体系结构代码质量增强功能。
  • 添加了 __vectorcall 调用约定。 使用 __vectorcall 调用约定来传递向量类型参数,从而使用向量寄存器。
  • 新链接器选项。 使用 /Gw(编译器)和 /Gy(汇编)开关,使链接器优化生成精简二进制文件。
  • C++ AMP 共享内存支持,可减少或消除 CPU 和 GPU 间的数据复制。

按配置优化选项 (PGO) 增强

  • 通过使用 PGO 实现已优化的应用程序工作集的缩减,从而提高性能。
  • 用于 Windows 运行时应用开发的新 PGO。

Windows 运行时应用开发支持

  • 现在可以使用可以为空的字段(例如,而不是)来定义值类型 IBox<int>^  。 这意味着字段可以具有值,也可以等于  。

  • C++/CX 支持能够在整个应用程序二进制接口 (ABI) 中获取和传播各种异常信息的新 Windows 错误模型;这包括调用堆栈和自定义消息字符串。

  • 现在可以重写用户定义的 Windows 运行时引用类型中的 ToString。

  • 公共 Windows 运行时 API 现在可标记为已弃用并可收到一条自定义消息,此消息显示为生成警告并可提供迁移指南。

  • 支持本机/JavaScript 互操作调试、Windows 运行时异常诊断和异步代码调试(windows 运行时和 PPL)。

 备注

除本节中介绍的 C++ 特定功能和增强功能外,Visual Studio 中的其他增强功能还可帮助你编写更好的 Windows 运行时应用。

诊断增强功能

  • 调试器改进。 支持异步调试和“仅我的代码”调试。
  • 代码分析类别。 现在可以查看代码分析器的分类输出,帮助您找到并修复代码缺陷。
  • XAML 诊断。 现在可以诊断 XAML 中的 UI 响应和电池使用情况问题。
  • 图像和 GPU 调试改进。
  • 在实际设备上远程捕获和重放。
  • 同步 C++ AMP 和 CPU 调试。
  • 改进的 C++ AMP 运行时诊断。
  • HLSL 计算着色器跟踪调试。

三维图形增强功能

  • 图像内容管线支持预乘 alpha DDS 格式。
  • 图像编辑器使用内部预乘 alpha 进行呈现,从而避免呈现暗的光晕等项目。
  • 图像和模型编辑器。 图像编辑器和模型编辑器的“着色器设计器”现在支持用户定义的筛选器创建。

IDE 与工作效率

。 您可以将多个格式设置应用于 C++ 代码。 使用这些设置,您可以控制大括号和关键字、缩进、间距和自动换行的新行位置。 当完成语句和块并且将代码粘贴到文件中时,代码将自动进行格式化。

 现在,C++ 代码会自动完成对应于这些开始字符的结束字符:

  • {(大括号)
  • [(方括号)
  • ((括号)
  • '(单引号)
  • "(双引号)

  • 添加用于类类型的分号。
  • 完成对原始字符串文本使用括号。
  • (/ * /) 完成多行注释 *

 在后台引用显示出文本匹配列表后自动对其进行解析和筛选。

 无法访问的成员已从 IntelliSense 成员列表中筛选出来。 例如,私有成员不会在成员列表中显示,除非您修改了实现此类型的代码。 打开成员列表时,可以按  +  删除筛选 (仅适用于当前成员列表窗口) 。 您可以再次按  +  删除文本筛选并显示每个成员。

 参数帮助工具提示中显示的函数签名现在将根据实际输入参数的数量而改变,而不是只显示一个随机的签名且不根据当前上下文更新。 函数显示在嵌套函数上时,参数也会适当地帮助函数。

 现在,通过使用快捷菜单或键盘快捷方式上的命令,可以在标题及其相应代码文件之间切换。

 在键入代码向 C++/CX 或 C++/CLI

标签: 4595连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台