Miglioramenti della conformità C++ in Visual Studio 2017 versioni 15.0, 15.3, 15.5, 15.6 e 15.7C++ conformance improvements in Visual Studio 2017 versions 15.0, 15.3, 15.5, 15.6, 15.7

Con il supporto per constexpr generalizzata e NSDMI per le aggregazioni, il compilatore di Microsoft Visual C++ è ora completo per le funzionalità aggiunte nello standard C++14.With support for generalized constexpr and NSDMI for aggregates, the Microsoft Visual C++ compiler is now complete for features added in the C++14 Standard. Si noti che il compilatore manca ancora di alcune funzionalità relative agli standard C++11 e C++98.Note that the compiler still lacks a few features from the C++11 and C++98 Standards. Vedere Visual C++ Language Conformance (Conformità al linguaggio Visual C++) per una tabella che mostra lo stato corrente del compilatore.See Visual C++ Language Conformance for a table that shows the current state of the compiler.

C++11C++11

Supporto di SFINAE per le espressioni in un maggior numero di librerieExpression SFINAE support in more libraries

Viene continuamente migliorato il supporto del compilatore per la regola SFINAE per le espressioni, necessario ai fini della deduzione e della sostituzione degli argomenti del modello in cui le espressioni decltype e constexpr possono apparire come parametri del modello.The compiler continues to improve its support for expression SFINAE, which is required for template argument deduction and substitution where decltype and constexpr expressions may appear as template parameters. Per altre informazioni, vedere il blog relativo ai miglioramenti dell'espressione SFINAE in Visual Studio 2017 RC.For more information, see Expression SFINAE improvements in Visual Studio 2017 RC.

C++ 14C++ 14

NSDMI per le aggregazioniNSDMI for Aggregates

Un'aggregazione è una matrice o una classe che non ha costruttori specificati dall'utente, membri dati non statici privati o protetti, classi di base e funzioni virtuali.An aggregate is an array or a class with no user-provided constructor, no private or protected non-static data members, no base classes, and no virtual functions. A partire da C++14 gli aggregati possono contenere inizializzatori di membro.Beginning in C++14 aggregates may contain member initializers. Per altre informazioni, vedere l'argomento relativo a inizializzatori di membro e aggregati.For more information, see Member initializers and aggregates.

constexpr estesoExtended constexpr

Le espressioni dichiarate come constexpr ora possono contenere determinati tipi di dichiarazioni, istruzioni if e switch, istruzioni loop e modifica di oggetti la cui durata è iniziata all'interno della valutazione dell'espressione constexpr.Expressions declared as constexpr are now allowed to contain certain kinds of declarations, if and switch statements, loop statements, and mutation of objects whose lifetime began within the constexpr expression evaluation. Inoltre, non è più un requisito che una funzione membro non statica constexpr sia const in modo implicito.Also, there is no longer a requirement that a constexpr non-static member function be implicitly const. Per altre informazioni, vedere l'argomento relativo alla riduzione dei vincoli per le funzioni constexpr.For more information, see Relaxing constraints on constexpr functions.

C++17C++17

static_assert concisoTerse static_assert

Il parametro di messaggio per static_assert è facoltativo.the message parameter for static_assert is optional. Per altre informazioni, vedere il documento relativo all'estensione di static_assert, v2.For more information, see Extending static_assert, v2.

Attributo [[fallthrough]][[fallthrough]] attribute

In modalità /std:c++17 l'attributo [[fallthrough]] può essere usato nel contesto di istruzioni switch per suggerire al compilatore che il comportamento del fallthrough è previsto.In /std:c++17 mode, the [[fallthrough]] attribute can be used in the context of switch statements as a hint to the compiler that the fall-through behavior is intended. Ciò impedisce al compilatore di emettere avvisi in tali casi.This prevents the compiler from issuing warnings in such cases. Per altre informazioni, vedere il documento sulla definizione per l'attributo [[fallthrough]].For more information, see Wording for [[fallthrough]] attribute.

Cicli for basati su intervallo generalizzatiGeneralized range-based for loops

I cicli range-based for non richiedono più che begin() ed end() restituiscano oggetti dello stesso tipo.Range-based for loops no longer require that begin() and end() return objects of the same type. Ciò consente a end() di restituire un sentinel usato dagli intervalli in range-v3 e dalla specifica tecnica sugli intervalli, completa, ma non abbastanza pubblicata.This enables end() to return a sentinel as used by ranges in range-v3 and the completed-but-not-quite-published Ranges Technical Specification. Per altre informazioni, vedere Generalizing the Range-Based For Loop (Generalizzazione del ciclo for basato su intervallo).For more information, see Generalizing the Range-Based For Loop.

Miglioramenti in Visual Studio 2017 versione 15.3Improvements in Visual Studio 2017 version 15.3

Espressioni lambda di constexprconstexpr lambdas

È ora possibile usare espressioni lambda nelle espressioni costanti.Lambda expressions may now be used in constant expressions. Per altre informazioni, vedere Constexpr Lambda (Espressione lambda constexpr).For more information, see Constexpr Lambda.

if constexpr nei modelli di funzioneif constexpr in function templates

Un modello di funzione può contenere istruzioni if constexpr per abilitare il branching in fase di compilazione.A function template may contain if constexpr statements to enable compile-time branching. Per altre informazioni, vedere if constexpr.For more information, see if constexpr.

Istruzioni di selezione con inizializzatoriSelection statements with initializers

Un'istruzione if può includere un inizializzatore che introduce una variabile nell'ambito del blocco all'interno dell'istruzione stessa.An if statement may include an initializer that introduces a variable at block scope within the statement itself. Per altre informazioni, vedere Selection statements with initializer (Istruzioni di selezione con inizializzatore).For more information, see Selection statements with initializer.

Attributi [[maybe_unused]] e [[nodiscard]][[maybe_unused]] and [[nodiscard]] attributes

Nuovi attributi per ignorare gli avvisi quando non viene usata un'entità oppure per creare un avviso se il valore restituito di una chiamata di funzione viene rimosso.New attributes to silence warnings when an entity is not used, or to create a warning if the return value of a function call is discarded. Per altre informazioni, vedere Wording for maybe_unused attribute (Formulazione per l'attributo maybe_unused) e Proposal of unused,nodiscard and fallthrough attributes (Proposta per gli attributi unused, nodiscard e fallthrough).For more information, see Wording for maybe_unused attribute and Proposal of unused,nodiscard and fallthrough attributes.

Uso degli spazi dei nomi degli attributi senza ripetizioneUsing attribute namespaces without repetition

Nuova sintassi per consentire un solo identificatore dello spazio dei nomi in un elenco di attributi.New syntax to enable only a single namespace identifier in an attribute list. Per altre informazioni, vedere Attributes in C++ (Attributi in C++).For more information, see Attributes in C++.

Binding strutturatiStructured bindings

In una singola dichiarazione è ora possibile archiviare un valore con i nomi singoli dei relativi componenti, quando il valore è una matrice, std::tuple o std::pair oppure tutti i membri dati sono non statici e pubblici.It is now possible in a single declaration to store a value with individual names for its components, when the value is an array, a std::tuple or std::pair, or has all public non-static data members. Per altre informazioni, vedere Structured Bindings (Binding strutturati).For more information, see Structured Bindings.

Regole di costruzione per i valori di classi di enumerazioneConstruction rules for enum class values

È ora disponibile una conversione implicita (non verso un tipo di dati più piccolo) dal tipo sottostante di un'enumerazione con ambito all'enumerazione stessa, quando la definizione dell'enumerazione non introduce alcun enumeratore e l'origine usa la sintassi di inizializzazione elenco.There is now an implicit/non-narrowing conversion from a scoped enumeration's underlying type to the enumeration itself, when its definition introduces no enumerator and the source uses a list-initialization syntax. Per altre informazioni, vedere Regole di costruzione per i valori di classi di enumerazione.For more information, see Construction Rules for enum class Values.

Acquisizione di *this per valoreCapturing *this by value

L'oggetto *this in un'espressione lambda può ora essere acquisito per valore.The *this object in a lambda expression may now be captured by value. Ciò rende possibili scenari in cui l'espressione lambda viene richiamata in operazioni parallele e asincrone, in particolare nelle architetture di computer più recenti.This enables scenarios in which the lambda is invoked in parallel and asynchronous operations, especially on newer machine architectures. Per altre informazioni, vedere Lambda Capture of *this by Value as [=,*this] (Acquisizione di this per valore come [=,this] nelle espressioni lambda).For more information, see Lambda Capture of *this by Value as [=,*this].

Rimozione di operator++ per boolRemoving operator++ for bool

operator++ non è più supportato nei tipi bool.operator++ is no longer supported on bool types. Per altre informazioni, vedere Remove Deprecated operator++(bool) (Rimozione di operator++(bool) deprecato).For more information, see Remove Deprecated operator++(bool).

Rimozione della parola chiave "register" deprecataRemoving deprecated "register" keyword

La parola chiave register, precedentemente deprecata e ignorata dal compilatore, è stata ora rimossa dal linguaggio.The register keyword, previously deprecated (and ignored by the compiler), is now removed from the language. Per altre informazioni, vedere Remove Deprecated Use of the register Keyword (Rimozione della parola chiave register per uso deprecato).For more information, see Remove Deprecated Use of the register Keyword.

Per l'elenco completo dei miglioramenti apportati alla conformità fino a Visual Studio 2015 Update 3, vedere Visual C++: novità dalla versione 2003 alla 2015.For the complete list of conformance improvements up through Visual Studio 2015 Update 3, see Visual C++ What's New 2003 through 2015.

Miglioramenti in Visual Studio 2017 versione 15.5Improvements in Visual Studio 2017 version 15.5

Le funzionalità contrassegnate con [14] sono disponibili senza condizioni anche nella modalità /std:c++14.Features marked with [14] are available unconditionally even in /std:c++14 mode.

Nuova opzione del compilatore per constexpr contrassegnata come externNew compiler switch for extern constexpr

Nelle versioni precedenti di Visual Studio il compilatore assegna sempre un collegamento interno della variabile constexpr anche quando la variabile è contrassegnata come extern.In earlier versions of Visual Studio, the compiler always gave a constexpr variable internal linkage even when the variable was marked extern. In Visual Studio 2017 versione 15.5 una nuova opzione del compilatore, /Zc:externConstexpr, abilita il comportamento corretto conforme agli standard.In Visual Studio 2017 version 15.5, a new compiler switch, /Zc:externConstexpr, enables correct standards-conforming behavior. Per altre informazioni, vedere Collegamento extern constexpr.For more information, see extern constexpr linkage.

Rimozione delle specifiche di eccezione dinamicheRemoving Dynamic Exception Specifications

P0003R5 Le specifiche di eccezione dinamiche sono deprecate in C++11.P0003R5 Dynamic exception specifications were deprecated in C++11. La funzionalità è stata rimossa da C++17, ma la specifica (ancora) deprecata throw() viene conservata esclusivamente come alias per noexcept(true).the feature is removed from C++17, but the (still) deprecated throw() specification is retained strictly as an alias for noexcept(true). Per altre informazioni, vedere Dynamic exception specification removal and noexcept (Rimozione della specifica di eccezione dinamica e noexcept).For more information, see Dynamic exception specification removal and noexcept.

not_fn()not_fn()

P0005R4 not_fn sostituisce not1 e not2.P0005R4 not_fn is a replacement of not1 and not2.

Riformulazione di enable_shared_from_thisRewording enable_shared_from_this

P0033R1 enable_shared_from_this era stato aggiunto in C++11.P0033R1 enable_shared_from_this was added in C++11. Lo standard C++17 aggiorna la specifica per gestire meglio determinati casi limite.The C++17 Standard updates the specification to better handle certain corner cases. [14][14]

Splicing di mappe e setSplicing Maps And Sets

P0083R3 Questa funzionalità consente l'estrazione dei nodi dai contenitori associativi (ad esempio, map, set, unordered_map, unordered_set) che possono quindi essere modificati e nuovamente inseriti nello stesso contenitore o in un contenitore diverso che usa lo stesso tipo di nodo.P0083R3 This feature enables extraction of nodes from associative containers (e.g., map, set, unordered_map, unordered_set) which can then be modified and inserted back into the same container or a different container that uses the same node type. Un caso d'uso comune è l'estrazione di un nodo da std::map, la modifica della chiave e il reinserimento.(A common use case is to extract a node from a std::map, change the key, and reinsert.)

Deprecazione di parti superflue della libreriaDeprecating Vestigial Library Parts

P0174R2 Diverse funzionalità della libreria standard C++ sono state sostituite da funzionalità più recenti nel corso degli anni oppure si sono rivelate poco utili o problematiche.P0174R2 Several features of the C++ Standard library have been superceded by newer features over the years, or else have been found to be not very useful or to be problematic. Queste funzionalità sono ufficialmente deprecate in C++ 17.These features are officially deprecated in C++17.

Rimozione del supporto dell'allocatore in std::functionRemoving Allocator Support In std::function

P0302R1 Prima di C++17 il modello di classe std::function aveva diversi costruttori che accettavano un argomento allocatore.P0302R1 Prior to C++17 the class template std::function had several constructors that took an allocator argument. L'uso di allocatori in questo contesto era tuttavia problematico e la semantica non era chiara.However, the use of allocators in this context was problematic, and the semantics were unclear. Questi costruttori sono stati quindi rimossi.Therefore these contructors were removed.

Correzioni per not_fn()Fixes for not_fn()

P0358R1 La nuova formulazione per std::not_fn offre il supporto della propagazione della categoria di valori in caso di chiamata al wrapper.P0358R1 New wording for std::not_fn provides support of propagation of value category in case of wrapper invocation.

shared_ptr<T[]>, shared_ptr<T[N]>shared_ptr<T[]>, shared_ptr<T[N]>

P0414R2 Unione delle modifiche di shared_ptr da Library Fundamentals a C++17.P0414R2 Merging shared_ptr changes from Library Fundamentals to C++17. [14][14]

Correzione di shared_ptr per le matriciFixing shared_ptr for Arrays

P0497R0 Correzioni al supporto di shared_ptr per le matrici.P0497R0 Fixes to shared_ptr support for arrays. [14][14]

Chiarimento per insert_return_typeClarifying insert_return_type

P0508R0 I contenitori associativi con chiavi univoche e i contenitori non ordinati con chiavi univoche hanno una funzione membro insert che restituisce un tipo annidato insert_return_type.P0508R0 The associative containers with unique keys, and the unordered containers with unique keys have a member function insert that returns a nested type insert_return_type. Tale tipo restituito è ora definito come specializzazione di un tipo con parametri negli elementi Iterator e NodeType del contenitore.That return type is now defined as a specialization of a type that is parameterized on the Iterator and NodeType of the container.

Variabili inline per STLInline Variables For The STL

P0607R0P0607R0

Funzionalità Annex D deprecateAnnex D features deprecated

Annex D dello standard C++ contiene tutte le funzionalità deprecate, incluse shared_ptr::unique(), <codecvt> e namespace std::tr1.Annex D of the C++ standard contains all the features that have been deprecated, including shared_ptr::unique(), <codecvt>, and namespace std::tr1. Quando l'opzione del compilatore /std:c++17 è impostata, quasi tutte le funzionalità della libreria standard in Annex D vengono contrassegnate come deprecate.When the /std:c++17 compiler switch is set, almost all the Standard Library features in Annex D are marked as deprecated. Per altre informazioni, vedere Le funzionalità della libreria standard in Annex D vengono contrassegnate come deprecate.For more information, see Standard Library features in Annex D are marked as deprecated.

Lo spazio dei nomi std::tr2::sys in <experimental/filesystem> crea un avviso di deprecazione in /std:c++14 per impostazione predefinita e ora viene rimosso in /std:c++17 per impostazione predefinita.The std::tr2::sys namespace in <experimental/filesystem> now emits a deprecation warning under /std:c++14 by default, and is now removed under /std:c++17 by default.

La conformità negli elementi iostream è stata migliorata evitando un'estensione non standard (specializzazioni esplicite in-class).Improved conformance in iostreams by avoiding a non-Standard extension (in-class explicit specializations).

La libreria standard ora usa modelli di variabile internamente.The Standard Library now uses variable templates internally.

La libreria standard è stata aggiornata in risposta alle modifiche del compilatore C++17, incluse l'aggiunta di noexcept nel sistema dei tipi e la rimozione delle specifiche di eccezione dinamiche.The Standard Library has been updated in response to C++17 compiler changes, including the addition of noexcept in the type system and the removal of dynamic-exception-specifications.

Miglioramenti in Visual Studio 2017 versione 15.6Improvements in Visual Studio 2017 version 15.6

C++17 Library Fundamentals V1C++17 Library Fundamentals V1

P0220R1 incorpora la Library Fundamentals Technical Specification per C++17 nello standard.P0220R1 incorporates Library Fundamentals Technical Specification for C++17 into the standard. Include gli aggiornamenti a <experimental/tuple>, <experimental/optional>, <experimental/functional>, <experimental/any>, <experimental/string_view> , <experimental/memory>, <experimental/memory_resource> e <experimental/algorithm>.Covers updates to <experimental/tuple>, <experimental/optional>, <experimental/functional>, <experimental/any>, <experimental/string_view> , <experimental/memory>, <experimental/memory_resource>,and <experimental/algorithm>.

C++17 Miglioramento della deduzione dell'argomento del modello della classe per STLC++17 Improving Class Template Argument Deduction For The STL

P0739R0 Spostare adopt_lock_t in primo piano nell'elenco dei parametri per scoped_lock per abilitare un utilizzo coerente di scoped_lock.P0739R0 Move adopt_lock_t to front of parameter list for scoped_lock to enable consistent use of scoped_lock. Consentire al costruttore std::variant di partecipare alla risoluzione dell'overload in più casi per abilitare l'assegnazione delle copie.Allow std::variant constructor to participate in overload resolution in more cases, in order to enable copy assignment.

Miglioramenti in Visual Studio 2017 versione 15.7Improvements in Visual Studio 2017 version 15.7

C++17 Ridefinizione dell'ereditarietà dei costruttoriC++17 Rewording inheriting constructors

P0136R1 specifica che una dichiarazione using che assegna un nome a un costruttore rende ora visibili i costruttori della classe di base corrispondente alle inizializzazioni della classe derivata anziché dichiarare costruttori aggiuntivi della classe derivata.P0136R1 specifies that 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. Si tratta di una modifica rispetto a C++14.This is a change from C++14. In Visual Studio 2017 versione 15.7 e successive in modalità /std:c++17 il codice valido in C++14 che usa l'ereditarietà dei costruttori potrebbe non essere valido o avere una semantica diversa.In Visual Studio 2017 version 15.7 and later, in /std:c++17 mode, code that is valid in C++14 and uses inheriting constructors may not be valid or may have different semantics.

L'esempio seguente illustra il comportamento di C++14:The following example shows C++14 behavior:

struct A {
    template<typename T>
    A(T, typename T::type = 0);
    A(int);
};

struct B : A {
    using A::A;
    B(int n) = delete; // Error C2280
};

B b(42L); // Calls B<long>(long), which calls A(int)
          //  due to substitution failure in A<long>(long).

L'esempio seguente illustra il comportamento di /std:c++17 in Visual Studio 15.7:The following example shows /std:c++17 behavior in Visual Studio 15.7:

struct A {
    template<typename T>
    A(T, typename T::type = 0);
    A(int);
};

struct B : A {
    using A::A;
    B(int n)
    {
        //do something
    }
};

B b(42L); // now calls B(int)

C++17 Inizializzazione delle aggregazioni estesaC++17 Extended aggregate initialization

P0017R1P0017R1

Se il costruttore di una classe di base è non pubblico ma accessibile a una classe derivata, in modalità /std:c++17 in Visual Studio versione 15.7 non è più possibile usare parentesi graffe vuote per inizializzare un oggetto di tipo derivato.If the constructor of a base class is non-public, but accessible to a derived class, then under /std:c++17 mode in Visual Studio version 15.7 you can no longer use empty braces to initialize an object of the derived type.

L'esempio seguente illustra il comportamento conforme di C++14:The following example shows C++14 conformant behavior:

struct Derived;

struct Base {
    friend struct Derived;
private:
    Base() {}
};

struct Derived : Base {};

Derived d1; // OK. No aggregate init involved.
Derived d2 {}; // OK in C++14: Calls Derived::Derived()
               // which can call Base ctor.

In C++17 Derived è ora considerato un tipo di aggregazione; di conseguenza, l'inizializzazione di Base tramite il costruttore predefinito privato si verifica direttamente come parte della regola di inizializzazione delle aggregazioni estesa.In C++17, Derived is now considered an aggregate type; therefore, the initialization of Base via the private default constructor happens directly as part of the extended aggregate initialization rule. In precedenza, il costruttore privato Base veniva chiamato tramite il costruttore Derived e aveva esito positivo a causa della dichiarazione Friend.Previously, the Base private constructor was called via the Derived constructor and it succeeded because of the friend declaration.

L'esempio seguente illustra il comportamento di C++17 in Visual Studio versione 15.7 in modalità /std:c++17:The following example shows C++17 behavior in Visual Studio version 15.7 in /std:c++17 mode:

struct Derived;

struct Base {
    friend struct Derived;
private:
    Base() {}
};

struct Derived : Base {
    Derived() {} // add user-defined constructor
                 // to call with {} initialization
};

Derived d1; // OK. No aggregate init involved.

Derived d2 {}; // error C2248: 'Base::Base': cannot access
               // private member declared in class 'Base'

C++17 Dichiarazione di parametri di modello non di tipo con autoC++17 Declaring non-type template parameters with auto

P0127R2P0127R2

In modalità /std:c++17 il compilatore può ora dedurre il tipo di un argomento di modello non di tipo dichiarato con auto:In /std:c++17 mode, the compiler can now deduce the type of a non-type template argument that is declared with auto:

template <auto x> constexpr auto constant = x;

auto v1 = constant<5>;      // v1 == 5, decltype(v1) is int
auto v2 = constant<true>;   // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>;    // v3 == 'a', decltype(v3) is char

Con questa nuova funzionalità il codice C++14 valido potrebbe non essere valido o avere una semantica diversa.One impact of this new feature is that valid C++14 code may not be valid or may have different semantics. Ad esempio, alcuni overload precedentemente non validi sono ora validi.For example, some overloads which were previously invalid are now valid. L'esempio seguente illustra il codice C++14 che esegue la compilazione perché la chiamata a foo(p) è associata a foo(void*);.The following example shows C++14 code that compiles because the call to foo(p) is bound to foo(void*);. In Visual Studio 2017 versione 15.7 in modalità /std:c++17 il modello di funzione foo è la corrispondenza migliore.In Visual Studio 2017 version 15.7, in /std:c++17 mode, the foo function template is the best match.

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); // OK in C++14
}

L'esempio seguente illustra il codice C++17 in Visual Studio 15.7 in modalità /std:c++17:The following example shows C++17 code in Visual Studio 15.7 in /std:c++17 mode:

template <int N> struct A;
template <typename T, T N> int foo(A<N>*);

void foo(void *);

void bar(A<0> *p)
{
    foo(p); // C2280: 'int foo<int,0>(A<0>*)': attempting to reference a deleted function
}

C++17 Conversioni di stringhe elementari (parziale)C++17 Elementary string conversions (partial)

P0067R5 Funzioni di basso livello indipendenti dalle impostazioni locali per le conversioni tra numeri interi e stringhe e tra numeri a virgola mobile e stringhe.P0067R5 Low-level, locale-independent functions for conversions between integers and strings and between floating-point numbers and strings. (Supportate solo per i numeri interi a partire da Visual Studio 15.7 Preview 2).(As of Visual Studio 15.7 Preview 2, supported for integers only.)

C++20 Evitare il decadimento non necessario (parziale)C++20 Avoiding unnecessary decay (partial)

P0777R1 Aggiunge una differenziazione tra il concetto di "decadimento" e quello di semplice rimozione dei qualificatori const o reference.P0777R1 Adds differentiation between the concept of "decay" and that of simply removing const or reference qualifiers. In alcuni contesti il nuovo tratto di tipo remove_reference_t sostituisce decay_t.New type trait remove_reference_t replaces decay_t in some contexts. Il supporto di remove_cvref_t non è stato ancora implementato in Visual Studio 2017 versione 15.7 Preview 2.Support for remove_cvref_t is not yet implemented as of Visual Studio 2017 version 15.7 Preview 2.

C++17 Algoritmi paralleliC++17 Parallel algorithms

P0024R2 Parallelism TS è incorporato nello standard, con modifiche minori.P0024R2 The Parallelism TS is incorporated into the standard, with minor modifications.

C++17 hypot(x, y, z)C++17 hypot(x, y, z)

P0030R1 Aggiunge tre nuovi overload a std::hypot, per i tipi float, double e long double, ognuno dei quali ha tre parametri di input.P0030R1 Adds three new overloads to std::hypot, for types float, double, and long double, each of which has three input parameters.

C++17 <filesystem>C++17 <filesystem>

P0218R1 Adotta File System TS nello standard con alcune modifiche al testo.P0218R1 Adopts the File System TS into the standard with a few wording modifications.

C++17 Funzioni matematiche specialiC++17 Mathematical special functions

P0226R1 Adotta le specifiche tecniche precedenti per le funzioni matematiche speciali nell'intestazione <cmath> standard.P0226R1 Adopts previous technical specifications for Mathematical Special Functions into the standard <cmath> header.

C++17 Guide alla deduzione per STLC++17 Deduction guides for the STL

P0433R2 Esegue l'aggiornamento a STL per sfruttare i vantaggi dell'adozione di C++17 di P0091R3 che aggiunge il supporto della deduzione dell'argomento del modello della classe.P0433R2 Updates to STL to take advantage of C++17 adoption of P0091R3, which adds support for class template argument deduction.

C++17 Ripristino delle conversioni di stringhe elementariC++17 Repairing elementary string conversions

P0682R1 Spostare le nuove funzioni di conversione delle stringhe elementari da P0067R5 in una nuova intestazione <charconv> e apportare altri miglioramenti, incluso la modifica della gestione degli errori per l'utilizzo di std::errc anziché std::error_code.P0682R1 Move the new elementary string conversion functions from P0067R5 into a new header <charconv> and make other improvements, including changing error handling to use use std::errc instead of std::error_code.

C++17 constexpr per char_traits (parziale)C++17 constexpr for char_traits (partial)

P0426R1 Modifiche alle funzioni membro std::traits_type length, compare e find per rendere utilizzabile std::string_view nelle espressioni costanti.P0426R1 Changes to std::traits_type member functions length, compare, and find in order to make make std::string_view usable in constant expressions. (In Visual Studio 2017 versione 15.6, supportato solo per Clang/LLVM.(In Visual Studio 2017 version 15.6, supported for Clang/LLVM only. Nella versione 15.7 Preview 2, il supporto è pressoché completo anche per ClXX).In version 15.7 Preview 2, support is nearly complete for ClXX as well.)

Correzioni di bug in Visual Studio versioni 15.0, 15.3, 15.5, 15.7 e 15.8Bug fixes in Visual Studio versions 15.0, 15.3, 15.5, 15.7, and 15.8

Copy-list-initializationCopy-list-initialization

Visual Studio 2017 genera correttamente errori del compilatore relativi alla creazione di oggetti con gli elenchi di inizializzatori che non venivano rilevati in Visual Studio 2015 e potevano causare un arresto anomalo o un comportamento non definito in fase di esecuzione.Visual Studio 2017 correctly raises compiler errors related to object creation using initializer lists that were not caught in Visual Studio 2015 and could lead to crashes or undefined runtime behavior. In base a N4594 13.3.1.7p1, in copy-list-initialization, il compilatore deve prendere in considerazione un costruttore esplicito per la risoluzione dell'overload, ma deve generare un errore se viene scelto tale overload.As per N4594 13.3.1.7p1, in copy-list-initialization, the compiler is required to consider an explicit constructor for overload resolution, but must raise an error if that overload is actually chosen.

I seguenti due esempi vengono compilati in Visual Studio 2015 ma non in Visual Studio 2017.The following two examples compile in Visual Studio 2015 but not in Visual Studio 2017.

struct A
{
    explicit A(int) {}
    A(double) {}
};

int main()
{
    A a1 = { 1 }; // error C3445: copy-list-initialization of 'A' cannot use an explicit constructor
    const A& a2 = { 1 }; // error C2440: 'initializing': cannot convert from 'int' to 'const A &'

}

Per correggere l'errore, usare l'inizializzazione diretta:To correct the error, use direct initialization:

A a1{ 1 };
const A& a2{ 1 };

In Visual Studio 2015 il compilatore tratta erroneamente copy-list-initialization come l'oggetto copy-initialization normale, considerando solo la conversione dei costruttori per la risoluzione dell'overload.In Visual Studio 2015, the compiler erroneously treated copy-list-initialization in the same way as regular copy-initialization; it considered only converting constructors for overload resolution. Nell'esempio seguente Visual Studio 2015 sceglie MyInt(23) ma Visual Studio 2017 genera correttamente l'errore.In the following example, Visual Studio 2015 chooses MyInt(23) but Visual Studio 2017 correctly raises the error.

// From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1228
struct MyStore {
    explicit MyStore(int initialCapacity);
};

struct MyInt {
    MyInt(int i);
};

struct Printer {
    void operator()(MyStore const& s);
    void operator()(MyInt const& i);
};

void f() {
    Printer p;
    p({ 23 }); // C3066: there are multiple ways that an object of this type can be called with these arguments
}

Questo esempio è simile a quello precedente, ma viene generato un errore diverso.This example is similar to the previous one but raises a different error. L'esito è positivo in Visual Studio 2015 e negativo in Visual Studio 2017 con C2668.It succeeds in Visual Studio 2015 and fails in Visual Studio 2017 with C2668.

struct A {
    explicit A(int) {}
};

struct B {
    B(int) {}
};

void f(const A&) {}
void f(const B&) {}

int main()
{
    f({ 1 }); // error C2668: 'f': ambiguous call to overloaded function
}

Typedef deprecatiDeprecated typedefs

Visual Studio 2017 ora genera l'avviso corretto per i typedef deprecati dichiarati in una classe o uno struct.Visual Studio 2017 now issues the correct warning for deprecated typedefs that are declared in a class or struct. L'esempio seguente viene compilato senza avvisi in Visual Studio 2015, ma genera l'avviso C4996 in Visual Studio 2017.The following example compiles without warnings in Visual Studio 2015 but produces C4996 in Visual Studio 2017.

struct A
{
    // also for __declspec(deprecated)
    [[deprecated]] typedef int inttype;
};

int main()
{
    A::inttype a = 0; // C4996 'A::inttype': was declared deprecated
}

constexprconstexpr

Visual Studio 2017 genera correttamente un errore quando l'operando sinistro di un'operazione con valutazione condizionale non è valido in un contesto constexpr.Visual Studio 2017 correctly raises an error when the left-hand operand of a conditionally evaluating operation is not valid in a constexpr context. Il codice seguente viene compilato in Visual Studio 2015, ma non in Visual Studio 2017 (C3615 la funzione constexpr 'f' non può restituire un'espressione costante):The following code compiles in Visual Studio 2015 but not in Visual Studio 2017 (C3615 constexpr function 'f' cannot result in a constant expression):

template<int N>
struct array
{
    int size() const { return N; }
};

constexpr bool f(const array<1> &arr)
{
    return arr.size() == 10 || arr.size() == 11; // C3615
}

Per correggere l'errore, dichiarare la funzione array::size() come constexpr o rimuovere il qualificatore constexpr da f.To correct the error, either declare the array::size() function as constexpr or remove the constexpr qualifier from f.

Tipi di classe passati alle funzioni variadicClass types passed to variadic functions

In Visual Studio 2017 le classi o gli struct che vengono passati a una funzione variadic, ad esempio printf, devono essere facilmente copiabili.In Visual Studio 2017, classes or structs that are passed to a variadic function such as printf must be trivially copyable. Quando si passano tali oggetti il compilatore si limita a creare una copia bit per bit e non chiama il costruttore o distruttore.When passing such objects, the compiler simply makes a bitwise copy and does not call the constructor or destructor.

#include <atomic>
#include <memory>
#include <stdio.h>

int main()
{
    std::atomic<int> i(0);
    printf("%i\n", i); // error C4839: non-standard use of class 'std::atomic<int>'
                        // as an argument to a variadic function.
                        // note: the constructor and destructor will not be called;
                        // a bitwise copy of the class will be passed as the argument
                        // error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)':
                        // attempting to reference a deleted function

    struct S {
        S(int i) : i(i) {}
        S(const S& other) : i(other.i) {}
        operator int() { return i; }
    private:
        int i;
    } s(0);
    printf("%i\n", s); // warning C4840 : non-portable use of class 'main::S'
                      // as an argument to a variadic function
}

Per correggere l'errore, è possibile chiamare una funzione membro che restituisca un tipo facilmente copiabileTo correct the error, you can call a member function that returns a trivially copyable type,

    std::atomic<int> i(0);
    printf("%i\n", i.load());

o esegua un cast statico per convertire l'oggetto prima di passarlo:or else perform a static cast to convert the object before passing it:

    struct S {/* as before */} s(0);
    printf("%i\n", static_cast<int>(s))

Per le stringhe compilate e gestite usando CString, per il cast di un oggetto CString al puntatore C previsto dalla stringa di formato deve essere usato l'operator LPCTSTR() specificato.For strings built and managed using CString, the provided operator LPCTSTR() should be used to cast a CString object to the C pointer expected by the format string.

CString str1;
CString str2 = _T("hello!");
str1.Format(_T("%s"), static_cast<LPCTSTR>(str2));

Qualificatori CV nella costruzione di classicv-qualifiers in class construction

In Visual Studio 2015 il compilatore a volte ignora erroneamente il qualificatore CV quando genera un oggetto classe usando una chiamata al costruttore.In Visual Studio 2015, the compiler sometimes incorrectly ignores the cv-qualifier when generating a class object via a constructor call. Questo potenzialmente può causare un arresto anomalo o un comportamento imprevisto in fase di esecuzione.This can potentially cause a crash or unexpected runtime behavior. L'esempio seguente viene compilato in Visual Studio 2015, ma genera un errore del compilatore in Visual Studio 2017:The following example compiles in Visual Studio 2015 but raises a compiler error in Visual Studio 2017:

struct S
{
    S(int);
    operator int();
};

int i = (const S)0; // error C2440

Per correggere l'errore, dichiarare operator int() come const.To correct the error, declare operator int() as const.

Controllo dell'accesso per i nomi completi nei modelliAccess checking on qualified names in templates

Le versioni precedenti del compilatore non eseguivano il controllo dell'accesso per i nomi completi in alcuni contesti di modello.Previous versions of the compiler did not perform access checking on qualified names in some template contexts. Ciò può interferire con il comportamento previsto per SFINAE in cui la sostituzione deve avere esito negativo a causa della non accessibilità di un nome.This can interfere with expected SFINAE behavior where the substitution is expected to fail due to the inaccessibility of a name. Questo potrebbe avere causato un arresto anomalo o un comportamento imprevisto in fase di esecuzione perché il compilatore ha chiamato per errore l'overload dell'operatore non corretto.This could have potentially caused a crash or unexpected behavior at runtime due to the compiler incorrectly calling the wrong overload of the operator. In Visual Studio 2017 viene generato un errore del compilatore.In Visual Studio 2017, a compiler error is raised. L'errore specifico può variare, ma in genere è "C2672: non sono state trovate funzioni in overload corrispondenti".The specific error might vary but typically it is "C2672 no matching overloaded function found". Il codice seguente viene compilato in Visual Studio 2015 ma genera un errore in Visual Studio 2017:The following code compiles in Visual Studio 2015 but raises an error in Visual Studio 2017:

#include <type_traits>

template <class T> class S {
    typedef typename T type;
};

template <class T, std::enable_if<std::is_integral<typename S<T>::type>::value, T> * = 0>
bool f(T x);

int main()
{
    f(10); // C2672: No matching overloaded function found.
}

Elenchi di argomenti di modello mancantiMissing template argument lists

In Visual Studio 2015 e versioni precedenti il compilatore non diagnosticava gli elenchi di argomenti di modello mancanti quando il modello era visualizzato in un elenco di parametri di modello, ad esempio come parte di un argomento di modello predefinito o un parametro di modello non di tipo.In Visual Studio 2015 and earlier, the compiler did not diagnose missing template argument lists when the template appeared in a template parameter list (for example as part of a default template argument or a non-type template parameter). Ciò può causare un comportamento imprevedibile, compresi arresti anomali del compilatore o il comportamento imprevisto in fase di esecuzione.This can result in unpredictable behavior, including compiler crashes or unexpected runtime behavior. Il codice seguente viene compilato in Visual Studio 2015 ma genera un errore in Visual Studio 2017.The following code compiles in Visual Studio 2015 but produces an error in Visual Studio 2017.

template <class T> class ListNode;
template <class T> using ListNodeMember = ListNode<T> T::*;
template <class T, ListNodeMember M> class ListHead; // C2955: 'ListNodeMember': use of alias
                                                     // template requires template argument list

// correct:  template <class T, ListNodeMember<T> M> class ListHead;

Espressione SFINAEExpression-SFINAE

Per supportare l'espressione SFINAE, il compilatore ora analizza argomenti decltype quando i modelli vengono dichiarati senza creare un'istanza.To support expression-SFINAE, the compiler now parses decltype arguments when the templates are declared rather than instantiated. Di conseguenza, se viene rilevata una specializzazione non dipendente nell'argomento decltype, non viene rinviata all'ora di creazione di un'istanza ma viene elaborata immediatamente ed è possibile diagnosticare eventuali errori risultanti in quel momento.Consequently, if a non-dependent specialization is found in the decltype argument, it is not deferred to instantiation-time and is processed immediately and any resulting errors are diagnosed at that time.

Nell'esempio seguente viene illustrato questo tipo di errore del compilatore che viene generato al momento della dichiarazione:The following example shows such a compiler error that is raised at the point of declaration:

#include <utility>
template <class T, class ReturnT, class... ArgsT>
class IsCallable
{
public:
    struct BadType {};

    template <class U>
    static decltype(std::declval<T>()(std::declval<ArgsT>()...)) Test(int); //C2064. Should be declval<U>

    template <class U>
    static BadType Test(...);

    static constexpr bool value = std::is_convertible<decltype(Test<T>(0)), ReturnT>::value;
};

constexpr bool test1 = IsCallable<int(), int>::value;
static_assert(test1, "PASS1");
constexpr bool test2 = !IsCallable<int*, int>::value;
static_assert(test2, "PASS2");

Classi dichiarate in spazi dei nomi anonimiClasses declared in anonymous namespaces

In base allo standard C++, una classe dichiarata all'interno di uno spazio dei nomi anonimo include un collegamento interno e pertanto non può essere esportata.According to the C++ standard, a class declared inside an anonymous namespace has internal linkage, and therefore cannot be exported. In Visual Studio 2015 e versioni precedenti questa regola non viene applicata.In Visual Studio 2015 and earlier, this rule was not enforced. In Visual Studio 2017 la regola viene applicata parzialmente.In Visual Studio 2017 the rule is partially enforced. L'esempio seguente genera questo errore in Visual Studio 2017: "errore C2201: const anonymous namespace::S1::vftable: per l'esportazione e l'importazione è necessario utilizzare il collegamento esterno."The following example raises this error in Visual Studio 2017: "error C2201: const anonymous namespace::S1::vftable: must have external linkage in order to be exported/imported."

struct __declspec(dllexport) S1 { virtual void f() {} }; //C2201

Inizializzatori predefiniti per i membri della classe di valori (C++/CLI)Default initializers for value class members (C++/CLI)

In Visual Studio 2015 e versioni precedenti il compilatore consentiva, ma ignorava, un inizializzatore di membro predefinito per un membro di una classe di valori.In Visual Studio 2015 and earlier, the compiler permitted (but ignored) a default member initializer for a member of a value class. L'inizializzazione predefinita di una classe di valori inizializza sempre a zero i membri e un costruttore predefinito non è consentito.Default initialization of a value class always zero-initializes the members; a default constructor is not permitted. In Visual Studio 2017 gli inizializzatori di membri predefiniti generano un errore del compilatore, come illustra l'esempio seguente:In Visual Studio 2017, default member initializers raise a compiler error, as shown in this example:

value struct V
{
    int i = 0; // error C3446: 'V::i': a default member initializer
               // is not allowed for a member of a value class
};

Indicizzatori predefiniti (C++/CLI)Default Indexers (C++/CLI)

In Visual Studio 2015 e versioni precedenti il compilatore in alcuni casi identificava erroneamente una proprietà predefinita come indicizzatore predefinito.In Visual Studio 2015 and earlier, the compiler in some cases misidentified a default property as a default indexer. È stato possibile risolvere il problema usando l'identificatore default per accedere alla proprietà.It was possible to work around the issue by using the identifier default to access the property. Questa soluzione è diventata problematica dopo che default è stato introdotto come parola chiave in C++11.The workaround itself became problematic after default was introduced as a keyword in C++11. Pertanto, in Visual Studio 2017 sono stati corretti i bug che richiedevano la soluzione e il compilatore genera ora un errore quando si usa default per accedere alla proprietà predefinita per una classe.Therefore, in Visual Studio 2017 the bugs that required the workaround were fixed, and the compiler now raises an error when default is used to access the default property for a class.

//class1.cs

using System.Reflection;
using System.Runtime.InteropServices;

namespace ClassLibrary1
{
    [DefaultMember("Value")]
    public class Class1
    {
        public int Value
        {
            // using attribute on the return type triggers the compiler bug
            [return: MarshalAs(UnmanagedType.I4)]
            get;
        }
    }
    [DefaultMember("Value")]
    public class Class2
    {
        public int Value
        {
            get;
        }
    }
}

// code.cpp
#using "class1.dll"

void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)
{
       r1->Value; // error
       r1->default;
       r2->Value;
       r2->default; // error
}

In Visual Studio 2017 è possibile accedere a entrambe le proprietà Value in base al nome:In Visual Studio 2017, you can access both Value properties by their name:

#using "class1.dll"

void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)
{
       r1->Value;
       r2->Value;
}

Correzioni di bug in Visual Studio 2017 versione 15.3Bug fixes in Visual Studio 2017 version 15.3

Chiamate a modelli di membro eliminatiCalls to deleted member templates

Nelle versioni precedenti di Visual Studio, in alcuni casi il compilatore non riusciva a generare un errore in caso di chiamate non valide a un modello di membro eliminato che potevano causare arresti anomali in fase di runtime.In previous versions of Visual Studio, the compiler in some cases would fail to emit an error for ill-formed calls to a deleted member template which would’ve potentially caused crashes at runtime. Il codice seguente genera ora l'errore C2280, "'int S<int>::f<int>(void)': tentativo di fare riferimento a una funzione eliminata":The following code now produces C2280, "'int S<int>::f<int>(void)': attempting to reference a deleted function":

template<typename T>
struct S {
   template<typename U> static int f() = delete;
};

void g()
{
   decltype(S<int>::f<int>()) i; // this should fail
}

Per correggere l'errore, dichiarare i come int.To fix the error, declare i as int.

Controlli sulle precondizioni per tratti di tipoPre-condition checks for type traits

Visual Studio 2017 versione 15.3 migliora i controlli sulle precondizioni per i tratti di tipo in modo da attenersi più rigorosamente agli standard.Visual Studio 2017 version 15.3 improves pre-condition checks for type-traits to more strictly follow the standard. Un controllo di questo tipo verifica ad esempio che il tratto di tipo sia assegnabile.One such check is for assignable. In Visual Studio 2017 versione 15.3 il codice seguente genera l'errore C2139:The following code produces C2139 in Visual Studio 2017 version 15.3:

struct S;
enum E;

static_assert(!__is_assignable(S, S), "fail"); // C2139 in 15.3
static_assert(__is_convertible_to(E, E), "fail"); // C2139 in 15.3

Nuovi controlli di avviso e di runtime del compilatore sul marshalling da nativo a gestitoNew compiler warning and runtime checks on native-to-managed marshaling

Le chiamate da funzioni gestite a funzioni native richiedono il marshalling.Calling from managed functions to native functions requires marshalling. CLR esegue il marshalling ma non comprende la semantica di C++.The CLR performs the marshaling but it doesn't understand C++ semantics. Se si passa un oggetto nativo per valore, CLR chiama il costruttore di copia dell'oggetto o usa BitBlt, da cui può derivare un comportamento non definito in fase di runtime.If you pass a native object by value, CLR either calls the object's copy-constructor or uses BitBlt, which may cause undefined behavior at runtime.

Il compilatore genera ora un avviso se riesce a sapere in fase di runtime che tra il limite nativo e quello gestito viene passato per valore un oggetto con costruttore di copia eliminato.Now the compiler emits a warning if it can know at compile time that a native object with deleted copy ctor is passed between native and managed boundary by value. Se il compilatore non viene a conoscenza di questo evento in fase di runtime, inserisce un controllo di runtime in modo che il programma chiami immediatamente std::terminate nel momento in cui si verifica un marshalling non valido.For those cases in which the compiler doesn't know at compile time, it injects a runtime check so that the program calls std::terminate immediately when an ill-formed marshalling occurs. In Visual Studio 2017 versione 15.3 il codice seguente genera l'avviso C4606 "'A': per il passaggio dell'argomento per valore tra limite nativo e gestito è necessario un costruttore di copia valido.In Visual Studio 2017 version 15.3, the following code produces warning C4606 "'A': passing argument by value across native and managed boundary requires valid copy constructor. In caso contrario, il comportamento del runtime risulta non definito".Otherwise the runtime behavior is undefined".

class A
{
public:
   A() : p_(new int) {}
   ~A() { delete p_; }

   A(A const &) = delete;
   A(A &&rhs) {
   p_ = rhs.p_;
}

private:
   int *p_;
};

#pragma unmanaged

void f(A a)
{
}

#pragma managed

int main()
{
    f(A()); // This call from managed to native requires marshalling. The CLR doesn't understand C++ and uses BitBlt, which results in a double-free later.
}

Per correggere l'errore, rimuovere la direttiva #pragma managed per contrassegnare il chiamante come nativo ed evitare il marshalling.To fix the error, remove the #pragma managed directive to mark the caller as native and avoid marshalling.

Avviso di API sperimentale per WinRTExperimental API warning for WinRT

Le API WinRT rilasciate a scopo di sperimentazione e feedback vengono contrassegnate con Windows.Foundation.Metadata.ExperimentalAttribute.WinRT APIs that are released for experimentation and feedback are decorated with Windows.Foundation.Metadata.ExperimentalAttribute. In Visual Studio 2017 versione 15.3 il compilatore genera l'avviso C4698 quando rileva questo attributo.In Visual Studio 2017 version 15.3, the compiler produces warning C4698 when it encounters the attribute. Alcune API presenti in versioni precedenti di Windows SDK sono già state contrassegnate con questo attributo e le chiamate a queste API attivano ora l'avviso del compilatore.A few APIs in previous versions of the Windows SDK have already been decorated with the attribute, and calls to these APIs now trigger this compiler warning. Nelle nuove versioni di Windows SDK l'attributo è rimosso da tutti i tipi distribuiti, ma se si usa un SDK precedente sarà necessario eliminare questi avvisi per tutte le chiamate effettuate ai tipi distribuiti.Newer Windows SDKs have the attribute removed from all shipped types, but if you are using an older SDK, you'll need to suppress these warnings for all calls to shipped types.

Il codice seguente genera l'avviso C4698: "'Windows::Storage::IApplicationDataStatics2::GetForUserAsync' viene usato solo a scopo di valutazione e potrebbe essere modificato o rimosso in aggiornamenti futuri":The following code produces warning C4698: "'Windows::Storage::IApplicationDataStatics2::GetForUserAsync' is for evaluation purposes only and is subject to change or removal in future updates":

Windows::Storage::IApplicationDataStatics2::GetForUserAsync(); //C4698

Per disabilitare l'avviso, aggiungere #pragma:To disable the warning, add a #pragma:

#pragma warning(push)
#pragma warning(disable:4698)

Windows::Storage::IApplicationDataStatics2::GetForUserAsync();

#pragma warning(pop)

Definizione out-of-line di una funzione membro di modelloOut-of-line definition of a template member function

Visual Studio 2017 versione 15.3 genera un errore quando rileva una definizione out-of-line di una funzione membro di modello non dichiarata nella classe.Visual Studio 2017 version 15.3 produces an error when it encounters an out-of-line definition of a template member function that was not declared in the class. Il codice seguente genera ora l'errore C2039: 'f': non è un membro di 'S':The following code now produces error C2039: 'f': is not a member of 'S':

struct S {};

template <typename T>
void S::f(T t) {} //C2039: 'f': is not a member of 'S'

Per correggere l'errore, aggiungere una dichiarazione alla classe:To fix the error, add a declaration to the class:

struct S {
    template <typename T>
    void f(T t);
};
template <typename T>
void S::f(T t) {}

Tentativo di accettare l'indirizzo del puntatore "this"Attempting to take the address of "this" pointer

In C++ this è un prvalue di tipo puntatore a X. Non è possibile accettare l'indirizzo di this o associarlo a un riferimento lvalue.In C++ this is an prvalue of type pointer to X. You cannot take the address of this or bind it to an lvalue reference. Nelle versioni precedenti di Visual Studio, il compilatore consentiva di ignorare questa restrizione eseguendo un cast.In previous versions of Visual Studio, the compiler would allow you to circumvent this restriction by performing a cast. In Visual Studio 2017 versione 15.3, il compilatore genera l'errore C2664.In Visual Studio 2017 version 15.3, the compiler produces error C2664.

Conversione a una classe di base inaccessibileConversion to an inaccessible base class

Visual Studio 2017 versione 15.3 genera un errore quando si tenta di convertire un tipo in una classe di base inaccessibile.Visual Studio 2017 version 15.3 produces an error when you attempt to convert a type to a base class which is inaccessible. L'errore ora generato dal compilatore è "errore C2243: 'type cast': conversione da 'D *' a 'B *' esistente ma inaccessibile".The compiler now raises "error C2243: 'type cast': conversion from 'D *' to 'B *' exists, but is inaccessible". Il codice seguente non è valido e può causare un arresto anomalo in fase di runtime.The following code is ill-formed and can potentially cause a crash at runtime. Il compilatore genera ora un errore C2243 quando rileva un codice simile al seguente:The compiler now produces C2243 when it encounters code like this:

#include <memory>

class B { };
class D : B { }; // C2243. should be public B { };

void f()
{
   std::unique_ptr<B>(new D());
}

Gli argomenti predefiniti non sono consentiti nelle definizioni out-of-line di funzioni membroDefault arguments are not allowed on out of line definitions of member functions

Gli argomenti predefiniti non sono consentiti nelle definizioni out-of-line di funzioni membro presenti in classi modello. Il compilatore genererà un avviso in /permissive e un errore grave in /permissive-.Default arguments are not allowed on out-of-line definitions of member functions in template classes The compiler will issue a warning under /permissive, and a hard error under /permissive-.

Nelle versioni precedenti di Visual Studio, il codice non valido seguente poteva causare potenzialmente un arresto anomalo in fase di runtime.In previous versions of Visual Studio, the following ill-formed code could potentially cause a runtime crash. Visual Studio 2017 versione 15.3 genera l'avviso C5034: 'A<T>::f': una definizione out-of-line di un membro di una classe non può contenere argomenti predefiniti:Visual Studio 2017 version 15.3 produces warning C5034: 'A<T>::f': an out-of-line definition of a member of a class template cannot have default arguments:

template <typename T>
struct A {
    T f(T t, bool b = false);
};

template <typename T>
T A<T>::f(T t, bool b = false) // C5034
{
    // ...
}

Per correggere l'errore, rimuovere l'argomento predefinito = false.To fix the error, remove the = false default argument.

Uso di offsetof con indicatore di membro compostoUse of offsetof with compound member designator

In Visual Studio 2017 versione 15.3 l'uso di offsetof(T, m) dove m è un "indicatore di membro composto" genera un avviso se si esegue la compilazione con l'opzione /Wall.In Visual Studio 2017 version 15.3, using offsetof(T, m) where m is a "compound member designator" results in a warning when you compile with the /Wall option. Il codice seguente non è valido e può causare un arresto anomalo in fase di runtime.The following code is ill-formed and could potentially cause a crash at runtime. Visual Studio 2017 versione 15.3 produce l'avviso C4841: "è stata usata un'estensione non standard: indicatore di membro composto usato in offsetof":Visual Studio 2017 version 15.3 produces "warning C4841: non-standard extension used: compound member designator in offsetof":

struct A {
   int arr[10];
};

// warning C4841: non-standard extension used: compound member designator in offsetof
constexpr auto off = offsetof(A, arr[2]);

Per correggere il codice, disabilitare l'avviso con un pragma o modificare il codice in modo da non usare offsetof:To fix the code, either disable the warning with a pragma or change the code to not use offsetof:

#pragma warning(push)
#pragma warning(disable: 4841)
constexpr auto off = offsetof(A, arr[2]);
#pragma warning(pop)

Uso di offsetof con una funzione membro o un membro dati staticiUsing offsetof with static data member or member function

In Visual Studio 2017 versione 15.3 l'uso di offsetof(T, m) dove m fa riferimento a un membro dati statici o a una funzione membro determina un errore.In Visual Studio 2017 version 15.3, using offsetof(T, m) where m refers to a static data member or a member function results in an error. Il codice seguente produce l'errore C4597: "undefined behavior: offsetof applied to member function 'foo'" (comportamento indefinito: offsetof applicato alla funzione membro 'foo') e l'errore C4597: "undefined behavior: offsetof applied to static data member 'bar'" (comportamento indefinito: offsetof applicato al membro dati statici 'bar'):The following code produces "error C4597: undefined behavior: offsetof applied to member function 'foo'" and "error C4597: undefined behavior: offsetof applied to static data member 'bar'":

#include <cstddef>

struct A {
   int foo() { return 10; }
   static constexpr int bar = 0;
};

constexpr auto off = offsetof(A, foo);
constexpr auto off2 = offsetof(A, bar);

Questo codice non è valido e può causare un arresto anomalo in fase di runtime.This code is ill-formed and could potentially cause a crash at runtime. Per correggere l'errore, modificare il codice in modo da non richiamare più un comportamento indefinito.To fix the error, change the code to no longer invoke undefined behavior. Si tratta di codice non portabile non consentito dallo standard C++.This is non-portable code that is disallowed by the C++ standard.

Nuovo avviso per attributi declspecNew warning on declspec attributes

In Visual Studio 2017 versione 15.3 il compilatore non ignora più gli attributi se prima della specifica di collegamento extern "C" viene applicato __declspec(...).In Visual Studio 2017 version 15.3, the compiler no longer ignores attributes if __declspec(...) is applied before extern "C" linkage specification. In precedenza, il compilatore avrebbe ignorato l'attributo, con possibili implicazioni in fase di runtime.Previously, the compiler would ignore the attribute, which could have runtime implications. Se sono state impostate le opzioni /Wall e /WX, il codice seguente produce l'avviso C4768: "gli attributi __declspec prima della specifica del collegamento vengono ignorati":When the /Wall and /WX options are set, the following code produces "warning C4768: __declspec attributes before linkage specification are ignored":

__declspec(noinline) extern "C" HRESULT __stdcall //C4768

Per risolvere il problema, inserire prima la specifica "C" esterna:To fix the warning, put extern "C" first:

extern "C" __declspec(noinline) HRESULT __stdcall

Questo avviso è disattivato per impostazione predefinita nella versione 15.3, ma è attivato per impostazione predefinita nella versione 15.5 e influisce solo su codice compilato con /Wall /WX.This warning is off by default in 15.3, but on by default in 15.5, and only impacts code compiled with /Wall /WX.

decltype e chiamate a distruttori eliminatidecltype and calls to deleted destructors

Nelle versioni precedenti di Visual Studio, il compilatore non era in grado di rilevare se si verificava una chiamata a un distruttore eliminato nel contesto dell'espressione associata a 'decltype'.In previous versions of Visual Studio, the compiler did not detect when a call to a deleted destructor occurred in the context of the expression associated with 'decltype'. In Visual Studio 2017 versione 15.3 il codice seguente genera "errore C2280: 'A<T>::~A(void)': tentativo di fare riferimento a una funzione eliminata":In Visual Studio 2017 version 15.3, the following code produces "error C2280: 'A<T>::~A(void)': attempting to reference a deleted function":

template<typename T>
struct A
{
   ~A() = delete;
};

template<typename T>
auto f() -> A<T>;

template<typename T>
auto g(T) -> decltype((f<T>()));

void h()
{
   g(42);
}

Variabili const non inizializzateUninitialized const variables

Visual Studio 2017 RTW conteneva una regressione in cui il compilatore C++ non generava un messaggio di diagnostica se non veniva inizializzata una variabile 'const'.Visual Studio 2017 RTW release had a regression in which the C++ compiler would not issue a diagnostic if a 'const' variable was not initialized. Questa regressione è stata risolta in Visual Studio 2017 versione 15.3.This regression has been fixed in Visual Studio 2017 version 15.3. Il codice seguente produce ora "avviso C4132: 'Value': oggetto const da inizializzare":The following code now produces "warning C4132: 'Value': const object should be initialized":

const int Value; //C4132

Per correggere l'errore, assegnare un valore a Value.To fix the error, assign a value to Value.

Dichiarazioni vuoteEmpty declarations

Visual Studio 2017 versione 15.3 genera ora un avviso in presenza di dichiarazioni vuote per tutti i tipi, non solo per i tipi predefiniti.Visual Studio 2017 version 15.3 now warns on empty declarations for all types, not just built-in types. Il codice seguente genera ora un avviso C4091 di livello 2 per tutte le quattro dichiarazioni:The following code now produces a level 2 C4091 warning for all four declarations:

struct A {};
template <typename> struct B {};
enum C { c1, c2, c3 };

int;    // warning C4091 : '' : ignored on left of 'int' when no variable is declared
A;      // warning C4091 : '' : ignored on left of 'main::A' when no variable is declared
B<int>; // warning C4091 : '' : ignored on left of 'B<int>' when no variable is declared
C;      // warning C4091 : '' : ignored on left of 'C' when no variable is declared

Per rimuovere gli avvisi, è sufficiente impostare le dichiarazioni vuote come commento o rimuoverle.To remove the warnings, simply comment-out or remove the empty declarations. Se l'oggetto senza nome deve avere un effetto collaterale (ad esempio, RAII), è opportuno assegnare un nome all'oggetto.In cases where the un-named object is intended to have a side effect (such as RAII) it should be given a name.

L'avviso viene escluso in /Wv:18 ed è attivo per impostazione predefinita nel livello di avviso W2.The warning is excluded under /Wv:18 and is on by default under warning level W2.

std::is_convertible per i tipi matricestd::is_convertible for array types

Le versioni precedenti del compilatore restituiscono risultati non corretti per std::is_convertible per i tipi matrice.Previous versions of the compiler gave incorrect results for std::is_convertible for array types. Per questo motivo, gli autori delle librerie dovevano gestire come caso speciale il compilatore Microsoft Visual C++ quando veniva usato il tratto di tipo std::is_convertible<...>.This required library writers to special-case the Microsoft Visual C++ compiler when using the std::is_convertible<...> type trait. Nell'esempio seguente le asserzioni statiche hanno esito positivo nelle versioni precedenti di Visual Studio, ma negativo in Visual Studio 2017 versione 15.3:In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:

#include <type_traits>

using Array = char[1];

static_assert(std::is_convertible<Array, Array>::value);
static_assert(std::is_convertible<const Array, const Array>::value, "");
static_assert(std::is_convertible<Array&, Array>::value, "");
static_assert(std::is_convertible<Array, Array&>::value, "");

std::is_convertible<From, To> viene calcolato controllando se una definizione di funzione immaginaria è ben formata:std::is_convertible<From, To> is calculated by checking to see if an imaginary function definition is well formed:

   To test() { return std::declval<From>(); }

Distruttori privati e std::is_constructiblePrivate destructors and std::is_constructible

Le versioni precedenti del compilatore ignorano il fatto che un distruttore sia privato al momento di decidere il risultato di std::is_constructible.Previous versions of the compiler ignored whether a destructor was private when deciding the result of std::is_constructible. Questa condizione viene ora presa in considerazione.It now considers them. Nell'esempio seguente le asserzioni statiche hanno esito positivo nelle versioni precedenti di Visual Studio, ma negativo in Visual Studio 2017 versione 15.3:In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:

#include <type_traits>

class PrivateDtor {
   PrivateDtor(int) { }
private:
   ~PrivateDtor() { }
};

// This assertion used to succeed. It now correctly fails.
static_assert(std::is_constructible<PrivateDtor, int>::value);

A causa dei distruttori privati un tipo può essere non costruibile.Private destructors cause a type to be non-constructible. std::is_constructible<T, Args...> viene calcolato come se fosse scritta la dichiarazione seguente:std::is_constructible<T, Args...> is calculated as if the following declaration were written:

   T obj(std::declval<Args>()...)

Questa chiamata implica una chiamata al distruttore.This call implies a destructor call.

C2668: risoluzione ambigua dell'overloadC2668: Ambiguous overload resolution

Le versioni precedenti del compilatore talvolta non riescono a rilevare ambiguità quando vengono trovati più candidati sia tramite dichiarazioni che ricerche dipendenti dall'argomento.Previous versions of the compiler sometimes failed to detect ambiguity when it found multiple candidates via both using declarations and argument dependent lookup. Ciò può portare alla scelta di un overload non corretto e a un comportamento di runtime imprevisto.This can lead to wrong overload being chosen and unexpected runtime behavior. Nell'esempio seguente Visual Studio 2017 versione 15.3 genera correttamente C2668 'f': chiamata ambigua a funzione in overload:In the following example, Visual Studio 2017 version 15.3 correctly raises C2668 'f': ambiguous call to overloaded function:

namespace N {
   template<class T>
   void f(T&, T&);

   template<class T>
   void f();
}

template<class T>
void f(T&, T&);

struct S {};
void f()
{
   using N::f;

   S s1, s2;
   f(s1, s2); // C2668
}

Per correggere il codice, rimuovere l'istruzione using N::f se l'intenzione era di chiamare ::f().To fix the code, remove the using N::f statement if you intended to call ::f().

C2660: dichiarazioni di funzione locali e ricerca dipendente dall'argomentoC2660: local function declarations and argument dependent lookup

Le dichiarazioni di funzione locali nascondono la dichiarazione di funzione nell'ambito che la contiene e disabilitano la ricerca dipendente dall'argomento.Local function declarations hide the function declaration in the enclosing scope and disable argument dependent lookup. Tuttavia, le versioni precedenti del compilatore eseguono la ricerca dipendente dall'argomento in questo caso, causando potenzialmente la scelta dell'overload non corretto e un comportamento di runtime imprevisto.However, previous versions of the compiler performed argument dependent lookup in this case, potentially leading to the wrong overload being chosen and unexpected runtime behavior. In genere, l'errore è dovuto a una firma non corretta della dichiarazione di funzione locale.Typically, the error is due to an incorrect signature of the local function declaration. Nell'esempio seguente Visual Studio 2017 versione 15.3 genera correttamente C2660 'f': la funzione non accetta 2 argomenti:In the following example, Visual Studio 2017 version 15.3 correctly raises C2660 'f': function does not take 2 arguments:

struct S {};
void f(S, int);

void g()
{
   void f(S); // C2660 'f': function does not take 2 arguments:
   // or void f(S, int);
   S s;
   f(s, 0);
}

Per risolvere il problema, modificare la firma f(S) o rimuoverla.To fix the problem, either change the f(S) signature or remove it.

C5038: ordine di inizializzazione negli elenchi di inizializzatoriC5038: order of initialization in initializer lists

I membri di classe vengono inizializzati nell'ordine in cui sono dichiarati e non l'ordine in cui compaiono negli elenchi di inizializzatori.Class members are initialized in the order they are declared, not the order they appear in initializer lists. Le versioni precedenti del compilatore non avvisano quando l'ordine dell'elenco di inizializzatori è diverso dall'ordine di dichiarazione.Previous versions of the compiler did not warn when the order of the initializer list differed from the order of declaration. Ciò può causare un comportamento di runtime indefinito se l'inizializzazione di un membro dipende dal fatto che un altro membro nell'elenco sia già inizializzato.This could lead to undefined runtime behavior if the intialization of one member depended on another member in the list already being initialized. Nell'esempio seguente Visual Studio 2017 versione 15.3 (con /Wall) genera l'avviso C5038: "il membro dati 'A::y' verrà inizializzato dopo il membro dati 'A::x'":In the following example, Visual Studio 2017 version 15.3 (with /Wall) raises "warning C5038: data member 'A::y' will be initialized after data member 'A::x'":

struct A
{
    A(int a) : y(a), x(y) {} // Initialized in reverse, y reused
    int x;
    int y;
};

Per risolvere il problema, disporre l'elenco di inizializzatori nello stesso ordine delle dichiarazioni.To fix the problem, arrange the intializer list to have the same order as the declarations. Viene generato un avviso analogo quando uno o entrambi gli inizializzatori fanno riferimento a membri della classe di base.A similar warning is raised when one or both initializers refer to base class members.

Si noti che l'avviso è disattivato per impostazione predefinita e influisce solo sul codice compilato con /Wall.Note that the warning is off-by-default and only affects code compiled with /Wall.

Correzioni di bug e altre modifiche di comportamento in Visual Studio 2017 versione 15.5Bug fixes and other behavior changes in Visual Studio 2017 version 15.5

Modifica di ordinamento parzialePartial Ordering Change

Il compilatore ora rifiuta correttamente il codice seguente e visualizza il messaggio di errore corretto:The compiler now correctly rejects the following code and gives the correct error message:

template<typename... T>
int f(T* ...)
{
    return 1;
}

template<typename T>
int f(const T&)
{
    return 2;
}

int main()
{
    int i = 0;
    f(&i);    // C2668
}
t161.cpp
t161.cpp(16): error C2668: 'f': ambiguous call to overloaded function
t161.cpp(8): note: could be 'int f<int*>(const T &)'
        with
        [
            T=int*
        ]
t161.cpp(2): note: or       'int f<int>(int*)'
t161.cpp(16): note: while trying to match the argument list '(int*)'

Il problema nell'esempio precedente è la presenza di due differenze nei tipi (const rispetto a non-const e pack rispetto a non-pack).The problem in the example above is that there are two differences in the types (const vs. non-const and pack vs. non-pack). Per eliminare l'errore del compilatore, rimuovere una delle differenze.To eliminate the compiler error, remove one of the differences. In questo modo il compilatore può ordinare senza ambiguità le funzioni.This enables the compiler to unambiguously order the functions.

template<typename... T>
int f(T* ...)
{
    return 1;
}

template<typename T>
int f(T&)
{
    return 2;
}

int main()
{
    int i = 0;
    f(&i);
}

Gestori di eccezioniException handlers

I gestori del riferimento al tipo di matrice o di funzione non sono mai una corrispondenza per gli oggetti eccezione.Handlers of reference to array or function type are never a match for any exception object. Il compilatore ora rispetta correttamente questa regola e genera un avviso di livello 4.The compiler now correctly honors this rule and raises a level 4 warning. Non stabilisce neppure più una corrispondenza tra un gestore di char* o wchar_t* e un valore letterale stringa quando viene usato /Zc:strictStrings.It also no longer matches a handler of char* or wchar_t* to a string literal when /Zc:strictStrings is used.

int main()
{
    try {
        throw "";
    }
    catch (int (&)[1]) {} // C4843 (This should always be dead code.)
    catch (void (&)()) {} // C4843 (This should always be dead code.)
    catch (char*) {} // This should not be a match under /Zc:strictStrings
}
warning C4843: 'int (&)[1]': An exception handler of reference to array or function type is unreachable, use 'int*' instead
warning C4843: 'void (__cdecl &)(void)': An exception handler of reference to array or function type is unreachable, use 'void (__cdecl*)(void)' instead

Il codice seguente consente di evitare l'errore:The following code avoids the error:

catch (int (*)[1]) {}

Lo spazio dei nomi std::tr1 è deprecatostd::tr1 namespace is deprecated

Lo spazio dei nomi std::tr1 non standard è ora contrassegnato come deprecato in entrambe le modalità C++14 e C++17.The non-Standard std::tr1 namespace is now marked as deprecated in both C++14 and C++17 modes. In Visual Studio 2017 versione 15.5 il codice seguente genera l'errore C4996:In Visual Studio 2017 version 15.5, the following code raises C4996:

#include <functional>
#include <iostream>
using namespace std;

int main() {
    std::tr1::function<int (int, int)> f = std::plus<int>(); //C4996
    cout << f(3, 5) << std::endl;
    f = std::multiplies<int>();
    cout << f(3, 5) << std::endl;
}
warning C4996: 'std::tr1': warning STL4002: The non-Standard std::tr1 namespace and TR1-only machinery are deprecated and will be REMOVED. You can define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING to acknowledge that you have received this warning.

Per correggere l'errore, rimuovere il riferimento allo spazio dei nomi tr1:To fix the error, remove the reference to the tr1 namespace:

#include <functional>
#include <iostream>
using namespace std;

int main() {
    std::function<int (int, int)> f = std::plus<int>();
    cout << f(3, 5) << std::endl;
    f = std::multiplies<int>();
    cout << f(3, 5) << std::endl;
}

Funzionalità della libreria standard in Annex D contrassegnate come deprecateStandard Library features in Annex D are marked as deprecated

Quando l'opzione del compilatore in modalità /std:c++17 è impostata, quasi tutte le funzionalità della libreria standard in Annex D vengono contrassegnate come deprecate.When the /std:c++17 mode compiler switch is set, almost all Standard Library features in Annex D are marked as deprecated.

In Visual Studio 2017 versione 15.5 il codice seguente genera l'errore C4996:In Visual Studio 2017 version 15.5, the following code raises C4996:

#include <iterator>

class MyIter : public std::iterator<std::random_access_iterator_tag, int> {
public:
    // ... other members ...
};

#include <type_traits>

static_assert(std::is_same<MyIter::pointer, int*>::value, "BOOM");
warning C4996: 'std::iterator<std::random_access_iterator_tag,int,ptrdiff_t,_Ty*,_Ty &>::pointer': warning STL4015: The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. (The <iterator> header is NOT deprecated.) The C++ Standard has never required user-defined iterators to derive from std::iterator. To fix this warning, stop deriving from std::iterator and start providing publicly accessible typedefs named iterator_category, value_type, difference_type, pointer, and reference. Note that value_type is required to be non-const, even for constant iterators. You can define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.

Per correggere l'errore, seguire le istruzioni nel testo dell'avviso, come illustrato nel codice seguente:To fix the error, follow the instructions in the warning text, as demonstrated in the following code:

#include <iterator>

class MyIter {
public:
    typedef std::random_access_iterator_tag iterator_category;
    typedef int value_type;
    typedef ptrdiff_t difference_type;
    typedef int* pointer;
    typedef int& reference;

    // ... other members ...
};

#include <type_traits>

static_assert(std::is_same<MyIter::pointer, int*>::value, "BOOM");

Variabili locali senza riferimentiUnreferenced local variables

In Visual Studio 15.5 l'avviso C4189 viene generato in diversi casi, come illustrato nel codice seguente:In Visual Studio 15.5, warning C4189 is emitted in more cases, as shown in the following code:

void f() {
    char s[2] = {0}; // C4189. Either use the variable or remove it.
}
warning C4189: 's': local variable is initialized but not referenced

Per correggere l'errore, rimuovere la variabile non usata.To fix the error, remove the unused variable.

Commenti a riga singolaSingle line comments

In Visual Studio 2017 versione 15.5 gli avvisi C4001 e C4179 non vengono più generati dal compilatore C.In Visual Studio 2017 version 15.5, warnings C4001 and C4179 are no longer emitted by the C compiler. In precedenza venivano generati solo nell'opzione del compilatore /Za.Previously, they were only emitted under the /Za compiler switch. Gli avvisi non sono più necessari perché i commenti a riga singola fanno parte dello standard C da C99.The warnings are no longer needed because single line comments have been part of the C standard since C99.

/* C only */
#pragma warning(disable:4001) //C4619
#pragma warning(disable:4179)
// single line comment
//* single line comment */
warning C4619: #pragma warning: there is no warning number '4001'

Se non è necessario che il codice sia compatibile con le versioni precedenti, è possibile evitare l'avviso rimuovendo l'eliminazione di C4001/C4179.If the code does not need to be backwards compatible, you can avoid the warning by removing the C4001/C4179 suppression. Se è necessario che il codice sia compatibile con le versioni precedenti, eliminare solo C4619.If the code does need to be backward compatible, then suppress C4619 only.


/* C only */

#pragma warning(disable:4619)
#pragma warning(disable:4001)
#pragma warning(disable:4179)

// single line comment
/* single line comment */

Attributi __declspec con collegamento extern "C"__declspec attributes with extern "C" linkage

Nelle versioni precedenti di Visual Studio il compilatore ignora gli attributi __declspec(...) quando __declspec(...) viene applicato prima della specifica del collegamento extern "C".In earlier versions of Visual Studio, the compiler ignored __declspec(...) attributes when __declspec(...) was applied before the extern "C" linkage specification. Questo comportamento causa la generazione di codice non desiderato dall'utente, con possibili implicazioni per il runtime.This behavior caused code to be generated that user didn't intend, with possible runtime implications. L'avviso è stato aggiunto in Visual Studio versione 15.3, ma è disattivato per impostazione predefinita.The warning was added in Visual Studio version 15.3, but was off by default. In Visual Studio 2017 versione 15.5 l'avviso è abilitato per impostazione predefinita.In Visual Studio 2017 version 15.5, the warning is enabled by default.

__declspec(noinline) extern "C" HRESULT __stdcall //C4768
warning C4768: __declspec attributes before linkage specification are ignored

Per correggere l'errore, inserire la specifica del collegamento prima dell'attributo __declspec:To fix the error, place the linkage specification before the __declspec attribute:

extern "C" __declspec(noinline) HRESULT __stdcall

Questo nuovo avviso C4768 viene visualizzato in alcune intestazioni di Windows SDK fornite con Visual Studio 2017 15.3 o versione precedente (ad esempio, la versione 10.0.15063.0, nota anche come RS2 SDK).This new warning C4768 is given on some Windows SDK headers that were shipped with Visual Studio 2017 15.3 or older (for example: version 10.0.15063.0, also known as RS2 SDK). Le versioni successive di Windows SDK (in particolare, ShlObj.h e ShlObj_core.h) sono state tuttavia corrette in modo che non generino questo avviso.However, later versions of Windows SDK headers (specifically, ShlObj.h and ShlObj_core.h) have been fixed so that they do not produce this warning. Quando viene visualizzato questo avviso proveniente dalle azioni di Windows SDK, è possibile eseguire queste azioni:When you see this warning coming from Windows SDK headers, you can take these actions:

  1. Passare alla versione più recente di Windows SDK fornita con Visual Studio 2017 versione 15.5.Switch to the latest Windows SDK that came with Visual Studio 2017 version 15.5 release.
  2. Disattivare l'avviso prima e dopo l'elemento #include dell'istruzione dell'intestazione di Windows SDK:Turn off the warning around the #include of the Windows SDK header statement:
   #pragma warning (push)
   #pragma warning(disable:4768)
   #include <shlobj.h>
   #pragma warning (pop)

Collegamento Extern constexprExtern constexpr linkage

Nelle versioni precedenti di Visual Studio il compilatore assegna sempre un collegamento interno della variabile constexpr anche quando la variabile è contrassegnata come extern.In earlier versions of Visual Studio, the compiler always gave a constexpr variable internal linkage even when the variable was marked extern. In Visual Studio 2017 versione 15.5 una nuova opzione del compilatore (/Zc:externConstexpr) abilita il comportamento corretto conforme agli standard.In Visual Studio 2017 version 15.5, a new compiler switch (/Zc:externConstexpr) enables correct standards-conforming behavior. Questo diventerà infine il comportamento predefinito.Eventually this will become the default.

extern constexpr int x = 10;
error LNK2005: "int const x" already defined

Se un file di intestazione contiene una variabile dichiarata extern constexpr, è necessario contrassegnarla come __declspec(selectany) per combinarne correttamente le dichiarazioni duplicate:If a header file contains a variable declared extern constexpr, it needs to be marked __declspec(selectany) in order to correctly have its duplicate declarations combined:

extern constexpr __declspec(selectany) int x = 10;

typeid non può essere usato nel tipo di classe incompletotypeid can't be used on incomplete class type

Nelle versioni precedenti di Visual Studio il compilatore consente erroneamente il codice seguente, che restituisce informazioni sul tipo potenzialmente non corrette.In earlier versions of Visual Studio, the compiler incorrectly allowed the following code, resulting in potentially incorrect type information. In Visual Studio 2017 versione 15.5 il compilatore genera correttamente un errore:In Visual Studio 2017 version 15.5, the compiler correctly raises an error:

#include <typeinfo>

struct S;

void f() { typeid(S); } //C2027 in 15.5
error C2027: use of undefined type 'S'

Tipo di destinazione std::is_convertiblestd::is_convertible target type

std::is_convertible richiede che il tipo di destinazione sia un tipo restituito valido.std::is_convertible requires the target type to be a valid return type. Nelle versioni precedenti di Visual Studio il compilatore consente erroneamente i tipi astratti, il che può causare una risoluzione dell'overload non corretta e un comportamento di runtime indesiderato.In earlier versions of Visual Studio, the compiler incorrectly allowed abstract types, which might lead to incorrect overload resolution and unintended runtime behavior. Il codice seguente ora genera correttamente l'errore C2338:The following code now correctly raises C2338:

#include <type_traits>

struct B { virtual ~B() = 0; };
struct D : public B { virtual ~D(); };

static_assert(std::is_convertible<D, B>::value, "fail"); // C2338 in 15.5

Per evitare l'errore, quando si usa is_convertible, è consigliabile confrontare i tipi di puntatore perché un confronto dei tipi non puntatore potrebbe non riuscire se un tipo è astratto:To avoid the error, when using is_convertible you should compare pointer types because a non-pointer-type comparison might fail if one type is abstract:

#include <type_traits>

struct B { virtual ~B() = 0; };
struct D : public B { virtual ~D(); };

static_assert(std::is_convertible<D *, B *>::value, "fail");

Rimozione della specifica di eccezione dinamica e noexceptDynamic exception specification removal and noexcept

In C++17 throw() è un alias per noexcept, throw(<type list>) e throw(...) vengono rimossi e alcuni tipi possono includere noexcept.In C++17, throw() is an alias for noexcept, throw(<type list>) and throw(...) are removed, and certain types may include noexcept. Ciò può causare problemi di compatibilità di origine con il codice conforme a C++14 o versione precedente.This can cause source compatibility issues with code that conforms to C++14 or earlier. L'opzione /Zc:noexceptTypes- può essere usata per ripristinare la versione C++14 di noexcept durante l'uso della modalità C++ 17 in generale.The /Zc:noexceptTypes- switch can be used to revert to the C++14 version of noexcept while using C++17 mode in general. In questo modo è possibile aggiornare il codice sorgente per garantire la conformità a C++17 senza dover riscrivere contemporaneamente tutto il codice throw().This enables you to update your source code to conform to C++17 without having to rewrite all your throw() code at the same time.

Il compilatore ora diagnostica anche altre specifiche di eccezione non corrispondenti nelle dichiarazioni in modalità C++17 o con /permissive- con il nuovo avviso C5043.The compiler also now diagnoses more mismatched exception specifications in declarations in C++17 mode or with /permissive- with the new warning C5043.

Il codice seguente genera C5043 e C5040 in Visual Studio 2017 versione 15.5 quando viene applicata l'opzione /std:c++17:The following code generates C5043 and C5040 in Visual Studio 2017 version 15.5 when the /std:c++17 switch is applied:

void f() throw(); // equivalent to void f() noexcept;
void f() {} // warning C5043
void g() throw(); // warning C5040

struct A {
    virtual void f() throw();
};

struct B : A {
    virtual void f() { } // error C2694
};

Per rimuovere gli errori quando si usa ancora /std:c++17, aggiungere l'opzione /Zc:noexceptTypes- alla riga di comando o aggiornare il codice per usare noexcept, come illustrato nell'esempio seguente:To remove the errors while still using /std:c++17, either add the /Zc:noexceptTypes- switch to the command line, or else update your code to use noexcept, as shown in the following example:

void f() noexcept;
void f() noexcept { }
void g() noexcept(false);

struct A {
    virtual void f() noexcept;
};

struct B : A {
    virtual void f() noexcept { }
};

Variabili inlineInline variables

I membri dati static constexpr ora sono implicitamente inline, quindi la loro dichiarazione in una classe ora è la loro definizione.Static constexpr data members are now implicitly inline, which means that their declaration within a class is now their definition. L'uso di una definizione out-of-line per un membro dati static constexpr è ridondante e attualmente deprecato.Using an out-of-line definition for a static constexpr data member is redundant, and now deprecated. In Visual Studio 2017 versione 15.5 quando viene applicata l'opzione /std:c++17, il codice seguente ora genera l'avviso C5041 'size': la definizione out-of-line per il membro dati statico constexpr non è necessaria ed è deprecata in C++17:In Visual Studio 2017 version 15.5 when the /std:c++17 switch is applied, the following code now produces warning C5041 'size': out-of-line definition for constexpr static data member is not needed and is deprecated in C++17:

struct X {
    static constexpr int size = 3;
};
const int X::size; // C5041

Avviso C4768 relativo a extern "C" __declspec(...) attivo per impostazione predefinitaextern "C" __declspec(...) warning C4768 now on by default

L'avviso è stato aggiunto in Visual Studio 2017 versione 15.3, ma è disattivato per impostazione predefinita.The warning was added in Visual Studio 2017 version 15.3 but was off by default. In Visual Studio 2017 versione 15.5 è attivo per impostazione predefinita.In Visual Studio 2017 version 15.5 it is on by default. Per altre informazioni, vedere Nuovo avviso per attributi declspec.See New warning on declspec attributes for more information.

Funzioni impostate come predefinite e __declspec(nothrow)Defaulted functions and __declspec(nothrow)

Il compilatore consentiva la dichiarazione delle funzioni impostate come predefinite con __declspec(nothrow) quando le corrispondenti funzioni di base/membro permettevano le eccezioni.The compiler previously allowed defaulted functions to be declared with __declspec(nothrow) when the corresponding base/member functions permitted exceptions. Questo comportamento è contrario allo standard C++ e può causare un comportamento non definito in fase di esecuzione.This behavior is contrary to the C++ Standard and can cause undefined behavior at runtime. Lo standard richiede che tali funzioni vengano definite come eliminate se è presente una specifica di eccezione non corrispondente.The standard requires such functions to be defined as deleted if there is an exception specification mismatch. In /std:c++17 il codice seguente genera l'errore C2280 tentativo di fare riferimento a una funzione eliminata. La funzione è stata eliminata in modo implicito perché la specifica dell'eccezione esplicita è incompatibile con quella della dichiarazione implicita.:Under /std:c++17, the following code raises C2280 attempting to reference a deleted function. Function was implicitly deleted because the explicit exception specification is incompatible with that of the implicit declaration.:

struct A {
    A& operator=(const A& other) { // No exception specification; this function may throw.
        ...
    }
};

struct B : public A {
    __declspec(nothrow) B& operator=(const B& other) = default;
};

int main()
{
    B b1, b2;
    b2 = b1; // error C2280
}

Per correggere questo codice, rimuovere __declspec(nothrow) dalla funzione impostata come predefinita o rimuovere = default e fornire una definizione per la funzione con qualsiasi gestione delle eccezioni obbligatorie:To correct this code, either remove __declspec(nothrow) from the defaulted function, or remove = default and provide a definition for the function along with any required exception handling:

struct A {
    A& operator=(const A& other) {
        // ...
    }
};

struct B : public A {
    B& operator=(const B& other) = default;
};

int main()
{
    B b1, b2;
    b2 = b1;
}

noexcept e specializzazioni parzialinoexcept and partial specializations

Con noexcept nel sistema dei tipi, le specializzazioni parziali per la corrispondenza di determinati tipi disponibili per la chiamata potrebbero non essere compilate o non scegliere il modello primario a causa di una specializzazione parziale mancante per i puntatori alle funzioni noexcept.With noexcept in the type system, partial specializations for matching particular "callable" types may fail to compile or choose the primary template due to a missing partial specialization for pointers-to-noexcept-functions.

In questi casi potrebbe essere necessario aggiungere altre specializzazioni parziali per gestire i puntatori alle funzioni noexcept e i puntatori noexcept alle funzioni membro.In such cases, you may need to add additional partial specializations to handle the noexcept function pointers and noexcept pointers to member functions. Questi overload sono validi solo nella modalità /std:c++17.These overloads are only legal in /std:c++17 mode. Se è necessario mantenere la compatibilità con le versioni precedenti di C++14 e si sta scrivendo codice che viene usato da altri, è consigliabile proteggere questi nuovi overload in direttive #ifdef.If backwards-compatibility with C++14 must be maintained, and you are writing code that others consume, then you should guard these new overloads inside #ifdef directives. Se si usa un modulo autonomo, invece di usare clausole guard #ifdef, è possibile eseguire solo la compilazione con l'opzione /Zc:noexceptTypes-.If you are working in a self-contained module, then instead of using #ifdef guards you can just compile with the /Zc:noexceptTypes- switch.

Il codice seguente esegue la compilazione in /std:c++14, ma ha esito negativo in /std:c++17 con l'errore C2027: "uso del tipo non definito 'A<T>'":The following code compiles under /std:c++14 but fails under /std:c++17 with "error C2027:use of undefined type 'A<T>'":

template <typename T> struct A;

template <>
struct A<void(*)()>
{
    static const bool value = true;
};

template <typename T>
bool g(T t)
{
    return A<T>::value;
}

void f() noexcept {}

int main()
{
    return g(&f) ? 0 : 1; // C2027
}

Il codice seguente ha esito positivo in /std:c++17 perché il compilatore sceglie la nuova specializzazione parziale A<void (*)() noexcept>:The following code succeeds under /std:c++17 because the compiler chooses the new partial specialization A<void (*)() noexcept>:

template <typename T> struct A;

template <>
struct A<void(*)()>
{
    static const bool value = true;
};

template <>
struct A<void(*)() noexcept>
{
    static const bool value = true;
};

template <typename T>
bool g(T t)
{
    return A<T>::value;
}

void f() noexcept {}

int main()
{
    return g(&f) ? 0 : 1; // OK
}

Correzioni di bug e altre modifiche di comportamento in Visual Studio 2017 versione 15.7Bug fixes and other behavior changes in Visual Studio 2017 version 15.7

C++17 Argomento predefinito nel modello di classe primarioC++17 Default argument in the primary class template

La modifica del comportamento è una precondizione per la deduzione dell'argomento del modello per i modelli di classe - P0091R3 di cui è previsto il supporto completo in un'anteprima successiva di Visual Studio 2017 versione 15.7.This behavior change is a precondition for Template argument deduction for class templates - P0091R3, which is planned to be fully supported in a later preview of Visual Studio 2017 version 15.7.

In precedenza il compilatore ignorava l'argomento predefinito nel modello di classe primario.Previously, the compiler ignored the default argument in the primary class template.

template<typename T>
struct S {
    void f(int = 0);
};

template<typename T>
void S<T>::f(int = 0) {} // Re-definition necessary

In modalità /std:c++17 in Visual Studio 2017 versione 15.7 l'argomento predefinito non viene ignorato:In /std:c++17 mode in Visual Studio 2017 version 15.7, the default argument is not ignored:

template<typename T>
struct S {
    void f(int = 0);
};

template<typename T>
void S<T>::f(int) {} // Default argument is used

Risoluzione dei nomi dipendentiDependent name resolution

La modifica del comportamento è una precondizione per la deduzione dell'argomento del modello per i modelli di classe - P0091R3 di cui è previsto il supporto completo in un'anteprima successiva di Visual Studio 2017 versione 15.7.This behavior change is a precondition for Template argument deduction for class templates - P0091R3, which is planned to be fully supported in a later preview of Visual Studio 2017 version 15.7.

Nell'esempio seguente il compilatore in Visual Studio 15.6 e versioni precedenti risolve D::type in B<T>::type nel modello di classe primario.In the following example, the compiler in Visual Studio 15.6 and earlier resolves D::type to B<T>::type in the primary class template.

template<typename T>
struct B {
    using type = T;
};

template<typename T>
struct D : B<T*> {
    using type = B<T*>::type;
};

Visual Studio 2017 versione 15.7 in modalità /std:c++17 richiede la parola chiave typename nell'istruzione using in D. Senza typename il compilatore genera l'avviso C4346: 'B<T*>::type': nome dipendente non è un tipo e l'errore C2061: errore di sintassi: identificatore 'type':Visual Studio 2017 version 15.7, in /std:c++17 mode, requires the typename keyword in the using statement in D. Without typename the compiler raises warning C4346: 'B<T*>::type': dependent name is not a type and error C2061: syntax error: identifier 'type':

template<typename T>
struct B {
    using type = T;
};

template<typename T>
struct D : B<T*> {
    using type = typename B<T*>::type;
};

C++17 Attributo [[nodiscard]] - incremento del livello di avvisoC++17 [[nodiscard]] attribute - warning level increase

In Visual Studio 2017 versione 15.7 in modalità /std:c++17 il livello di avviso di C4834 ("il valore restituito della funzione con attributo 'nodiscard' verrà rimosso") viene incrementato da W3 a W1.In Visual Studio 2017 version 15.7 in /std:c++17 mode, the warning level of C4834 ("discarding return value of function with 'nodiscard' attribute") is increased from W3 to W1. È possibile disabilitare l'avviso con un cast a void o passando /wd:4834 al compilatoreYou can disable the warning with a cast to void, or by passing /wd:4834 to the compiler

[[nodiscard]] int f() { return 0; }

int main() {
    f(); // warning: discarding return value
         // of function with 'nodiscard'
}

Elenco di inizializzazione della classe di base per un costruttore di modello variadicVariadic template constructor base class initialization list

Nelle edizioni precedenti di Visual Studio, un elenco di inizializzazione della classe di base per un costruttore di modello variadic con argomenti del modello mancanti è erroneamente consentito senza errori.In previous editions of Visual Studio, a variadic template constructor base class initialization list that was missing template arguments was erroneously allowed without error. In Visual Studio 2017 versione 15.7 viene generato un errore del compilatore.In Visual Studio 2017 version 15.7, a compiler error is raised.

L'esempio di codice seguente in Visual Studio 2017 versione 15.7 genera l'errore C2614: D<int>: inizializzazione membro non valida: 'B' non è una base né un membroThe following code example in Visual Studio 2017 version 15.7 raises error C2614: D<int>: illegal member initialization: 'B' is not a base or member

template<typename T>
struct B {};

template<typename T>
struct D : B<T>
{

    template<typename ...C>
    D() : B() {} // C2614. Missing template arguments to B.
};

D<int> d;

Per correggere l'errore, modificare l'espressione B() in B<T>().To fix the error, change the B() expression to B<T>().

Inizializzazione aggregata di constexprconstexpr aggregate initialization

Le versioni precedenti del compilatore C++ gestiscono in modo non corretto l'inizializzazione aggregata constexpr, accettando codice non valido in cui l'elenco di inizializzazione di aggregazione include troppi elementi e producendo codegen non corretto.Previous versions of the C++ compiler incorrectly handled constexpr aggregate initialization; it accepted invalid code in which the aggregate-init-list had too many elements, and produced bad codegen for it. Il codice seguente è un esempio:The following code is an example of such code:

#include <array>
struct X {
    unsigned short a;
    unsigned char b;
};

int main() {
    constexpr std::array<X, 2> xs = {
        { 1, 2 },
        { 3, 4 }
    };
    return 0;
}

In Visual Studio 2017 versione 15.7 Update 3 e versioni successive, l'esempio precedente genera ora C2078 troppi inizializzatori.In Visual Studio 2017 version 15.7 update 3 and later, the previous example now raises C2078 too many initializers. L'esempio seguente mostra come correggere il codice.The following example shows how to fix the code. Durante l'inizializzazione di una std::array con elenchi di inizializzazione tra parentesi graffe, assegnare alla matrice interna un elenco tra parentesi graffe specifico:When initializing a std::array with nested brace-init-lists, give the inner array a braced-list of its own:

#include <array>
struct X {
    unsigned short a;
    unsigned char b;
};

int main() {
    constexpr std::array<X, 2> xs = {{ // note double braces
        { 1, 2 },
        { 3, 4 }
    }}; // note double braces
    return 0;
}

Correzioni di bug e modifiche funzionali in Visual Studio 2017 versione 15.8Bug fixes and behavior changes in Visual Studio 2017 version 15.8

typename per identificatori non qualificatitypename on unqualified identifiers

In modalità /permissive-, il compilatore non accetta più parole chiave typename spurie per gli identificatori non qualificati nelle definizioni di modelli di alias.In /permissive- mode, spurious typename keywords on unqualified identifiers in alias template definitions are no longer accepted by the compiler. Il codice seguente ora genera l'errore C7511 'T': la parola chiave 'typename' deve essere seguita da un nome completo:The following code now produces C7511 'T': 'typename' keyword must be followed by a qualified name:

template <typename T>
using  X = typename T;

Per correggere l'errore, è sufficiente modificare la seconda riga in using X = T;.To fix the error, simply change the second line to using X = T;.

__declspec() sul lato destro di definizioni di modelli di alias__declspec() on right side of alias template definitions

La parola chiave __declspec non è più consentita sul lato destro di una definizione di modello di alias.__declspec is no longer permitted on the right-hand-side of an alias template definition. In precedenza, questa veniva accettata dal compilatore ma veniva completamente ignorata e non risultava mai in un avviso di deprecazione quando l'alias veniva usato.This was previously accepted by the compiler but was completely ignored, and would never result in a deprecation warning when the alias was used.

Al suo posto è possibile usare l'attributo C++ standard [[deprecated]], che viene rispettato a partire da Visual Studio 2017 versione 15.6.The standard C++ attribute [[deprecated]] may be used instead, and will be respected as of Visual Studio 2017 version 15.6. Il codice seguente ora genera un errore C2760 errore di sintassi: token '__declspec' imprevisto. Previsto 'identificatore di tipo':The following code now produces C2760 syntax error: unexpected token '__declspec', expected 'type specifier':

template <typename T>
using X = __declspec(deprecated("msg")) T;

Per correggere l'errore, modificare il codice come segue (con l'attributo posizionato prima del segno '=' della definizione di alias):To fix the error, change to code to the following (with the attribute placed before the '=' of the alias definition):

template <typename T>
using  X [[deprecated("msg")]] = T;

Diagnostica della ricerca del nome in due fasiTwo-phase name lookup diagnostics

La ricerca del nome in due fasi richiede che i nomi non dipendenti usati nel corpo di modelli siano visibili per il modello in fase di definizione.Two-phase name lookup requires that non-dependent names used in template bodies must be visible to the template at definition time. In precedenza, il compilatore Microsoft C++ non cercava un nome non trovato fino al momento della creazione dell'istanza.Previously, the Microsoft C++ compiler would leave an unfound name un-looked-up until instantiation times. È ora necessario che i nomi non dipendenti siano associati al corpo del modello.Now, it requires that non-dependent names are bound in the template body.

Un modo in cui ciò può manifestarsi è con la ricerca in classi di base dipendenti.One way this can manifest is with lookup into dependent base classes. In precedenza, il compilatore consentiva l'uso di nomi definiti in classi di base dipendenti, perché sarebbero stati ricercati al momento della creazione di un'istanza, dopo la risoluzione di tutti i tipi.Previously, the compiler allowed the use of names that are defined in dependent base classes because they would be looked up during instantiation time when all the types are resolved. Ora codice di questo tipo viene considerato un errore.Now that code it is treated as an error. In questi casi è possibile forzare la ricerca della variabile in fase di creazione di un'istanza qualificandola con il tipo della classe di base o rendendola dipendente in altro modo, ad esempio aggiungendo un puntatore this->.In these cases you can force the variable to be looked up at instantiation time by qualifying it with the base class type or otherwise making it dependent, for example by adding a this-> pointer.

In modalità /permissive- il codice seguente ora genera l'errore C3861: 'base_value': identificatore non trovato:In /permissive- mode, the following code now raises C3861: 'base_value': identifier not found:

template <class T>
struct Base {
    int base_value = 42;
};

template <class T>
struct S : Base<T> {
    int f() {
        return base_value;
    }
};

Per correggere l'errore, modificare l'istruzione return in return this->base_value;.To fix the error, change the return statement to return this->base_value;.

dichiarazioni e definizioni con prototipo in namespace stdforward declarations and definitions in namespace std

Lo standard C++ non consente di aggiungere dichiarazioni o definizioni con prototipo nello spazio dei nomi (namespace) std.The C++ standard doesn't allow a user to add forward declarations or definitions into namespace std. L'aggiunta di dichiarazioni o definizioni allo spazio dei nomi std o a uno spazio dei nomi all'interno dello spazio dei nomi std ora risulta in un comportamento indefinito.Adding declarations or definitions to namespace std or to a namespace within namespace std now results in undefined behavior.

In futuro, Microsoft modificherà la posizione di definizione di alcuni tipi STL.At some time in the future, Microsoft will move the location where some STL types are defined. Quando questo avverrà, codice esistente che aggiunga dichiarazioni con prototipo allo spazio dei nomi std non funzionerà più.When this happens, it will break existing code that adds forward declarations to namespace std. Un nuovo avviso, C4643, consente di identificare tali problemi nel codice sorgente.A new warning, C4643, helps identify such source issues. Questo avviso, abilitato in modalità /default e disattivato per impostazione predefinita,The warning is enabled in /default mode and is off by default. interessa i programmi compilati con /Wall o /WX.It will impact programs that are compiled with /Wall or /WX.

Il codice seguente ora genera un errore C4643: Lo standard C++ non consente la dichiarazione con prototipo di 'vettore' nello spazio dei nomi std.The following code now raises C4643: Forward declaring 'vector' in namespace std is not permitted by the C++ Standard.

namespace std { 
    template<typename T> class vector; 
} 

Per correggere l'errore, usare una direttiva include anziché una dichiarazione con prototipo:To fix the error, use an include directive rather than a forward declaration:

#include <vector>

Costruttori con delega a se stessiConstructors that delegate to themselves

Secondo lo Standard C++, un compilatore deve generare un messaggio di diagnostica quando un costruttore di delega delega se stesso.The C++ Standard suggests that a compiler should emit a diagnostic when a delegating constructor delegates to itself. Nelle modalità /std:c++17 e /std:c++latest, il compilatore Microsoft C++ ora genera l'errore C7535: 'X::X': il costruttore di delega chiama se stesso.The Microsoft C++ compiler in /std:c++17 and /std:c++latest modes now raises C7535: 'X::X': delegating constructor calls itself.

Senza questo errore, il programma seguente viene compilato ma genera un ciclo infinito:Without this error, the following program will compile but will generate an infinite loop:

class X { 
public: 
    X(int, int); 
    X(int v) : X(v){}
}; 

Per evitare il ciclo infinito, delegare un altro costruttore:To avoid the infinite loop, delegate to a different constructor:

class X { 
public: 

    X(int, int); 
    X(int v) : X(v, 0) {} 
}; 

offsetof con espressioni costantioffsetof with constant expressions

La macro offsetof era tradizionalmente implementata tramite una macro che richiedeva un operatore reinterpret_cast.offsetof has traditionally been implemented using a macro that requires a reinterpret_cast. Questa operazione non è valida in contesti che richiedono un'espressione costante, ma tradizionalmente il compilatore Microsoft C++ la consentiva.This is illegal in contexts that require a constant expression, but the Microsoft C++ compiler has traditionally allowed it. La macro offsetof in dotazione con STL usa correttamente una funzione intrinseca del compilatore (__builtin_offsetof), ma molti sviluppatori hanno usato il trucco della macro per definire una macro offsetof personalizzata.The offsetof macro that is shipped as part of the STL correctly uses a compiler intrinsic (__builtin_offsetof), but many people have used the macro trick to define their own offsetof.

In Visual Studio 2017 versione 15.8, il compilatore vincola le aree in cui gli operatori reinterpret_cast possono comparire nella modalità predefinita per consentire la conformità del codice al comportamento C++ standard.In Visual Studio 2017 version 15.8, the compiler constrains the areas that these reinterpret_casts can appear in the default mode in order to help code conform to standard C++ behavior. In modalità /permissive-, i vincoli sono ancora più restrittivi.Under /permissive-, the constraints are even stricter. Se si usa il risultato di una macro offsetof in posizioni che richiedono espressioni costanti, il codice può generare l'avviso C4644 l'utilizzo del criterio offsetof basato su macro nelle espressioni costanti non è standard. Usare offsetof definito nella libreria standard C++ o C2975 argomento di modello non valido. Prevista espressione costante in fase di compilazione.Using the result of an offsetof in places that require constant expressions may result in code that issues warning C4644 usage of the macro-based offsetof pattern in constant expressions is non-standard; use offsetof defined in the C++ standard library instead or C2975 invalid template argument, expected compile-time constant expression.

Il codice seguente genera l'errore C4644 in modalità /default e /std:c++17 e l'errore C2975 in modalità /permissive-:The following code raises C4644 in /default and /std:c++17 modes, and C2975 in /permissive- mode:

struct Data { 
    int x; 
}; 

// Common pattern of user-defined offsetof 
#define MY_OFFSET(T, m) (unsigned long long)(&(((T*)nullptr)->m)) 

int main() 

{ 
    switch (0) { 
    case MY_OFFSET(Data, x): return 0; 
    default: return 1; 
    } 
} 

Per correggere l'errore, usare offsetof definita tramite <cstddef>:To fix the error, use offsetof as defined via <cstddef>:

#include <cstddef>  

struct Data { 
    int x; 
};  

int main() 
{ 
    switch (0) { 
    case offsetof(Data, x): return 0; 
    default: return 1; 
    } 
} 

qualificatori cv per le classi di base soggette all'espansione di pacchettocv-qualifiers on base classes subject to pack expansion

Le versioni precedenti del compilatore Microsoft C++ non rilevavano che una classe di base aveva qualificatori cv se era anche soggetta all'espansione di pacchetto.Previous versions of the Microsoft C++ compiler did not detect that a base-class had cv-qualifiers if it was also subject to pack expansion.

Nella modalità /permissive- di Visual Studio 2017 versione 15.8, il codice seguente genera l'errore C3770 'const S': non è una classe base valida:In Visual Studio 2017 version 15.8, in /permissive- mode the following code raises C3770 'const S': is not a valid base class:

template<typename... T> 
class X : public T... { };  

class S { };  

int main() 
{ 
    X<const S> x; 
} 

parola chiave template e identificatori di nome annidatitemplate keyword and nested-name-specifiers

In modalità /permissive-, il compilatore richiede ora che la parola chiave template preceda il nome di un modello quando questo segue un identificatore di nome annidato da cui è dipendente.In /permissive- mode, the compiler now requires the template keyword to precede a template-name when it comes after a nested-name-specifier which is dependent.

Il codice seguente in modalità /permissive- ora genera l'errore C7510: 'foo': se si usa il nome di tipo dipendente, è necessario aggiungere il prefisso 'template'. note: vedere il riferimento all'istanza de modello di classe 'X' in corso di compilazione:The following code in /permissive- mode now raises C7510: 'foo': use of dependent template name must be prefixed with 'template'. note: see reference to class template instantiation 'X' being compiled:

template<typename T> struct Base
{
    template<class U> void foo() {} 
}; 

template<typename T> 
struct X : Base<T> 
{ 
    void foo() 
    { 
        Base<T>::foo<int>(); 
    } 
}; 

Per correggere l'errore, aggiungere la parola chiave template all'istruzione Base<T>::foo<int>(); , come illustrato nell'esempio seguente:To fix the error, add the template keyword to the Base<T>::foo<int>(); statement, as shown in the following example:

template<typename T> struct Base
{
    template<class U> void foo() {}
};

template<typename T> 
struct X : Base<T> 
{ 
    void foo() 
    { 
        // Add template keyword here:
        Base<T>::template foo<int>(); 
    } 
}; 

Vedere ancheSee also

Conformità al linguaggio di Visual C++Visual C++ Language Conformance