2016-03-08 30 views
7

perche il seguente frammento di codice:Possiamo fare riferimento alle variabili membro in una specifica noexcept?

template<class Tuple> 
class vector 
{ 
public: 
    typename Tuple::size_type size() const noexcept(noexcept(m_elements.size())) { 
     return m_elements.size(); 
    } 

private: 
    Tuple m_elements; 
}; 

class tuple 
{ 
public: 
    using size_type = std::size_t; 

    size_type size() const { return 0; } 
    size_type size() noexcept { return 0; } 
};  

int main() 
{ 
    vector<tuple> x; 
    static_assert(noexcept(x.size()), "x.size() might throw"); 

    return 0; 
} 

è l'uso della variabile membro m_elements all'interno del noexcept identificatore legale? GCC 5.2 (C++17) yields the compiler errorm_elements non è stato dichiarato in questo ambito. mentre clang 3.6 (C++17) compiles without any error.

Entrambi i compilatori non restituiscono alcun errore se si utilizza invece noexcept(std::declval<Tuple const&>().size()). Tuttavia, come puoi vedere, ho creato una semplice classe di esempio tuple in cui è fondamentale se loha sovraccarichi qualificati di size.

Dal mio punto di vista, è più intuitivo per scrivere noexcept(m_elements.size()) causa è esattamente la chiamata nel corpo della funzione e tiene conto che il metodo di vectorsize è const qualificata (che rende m_elements un oggetto const nell'ambito di la funzione).

Quindi, qual è l'utilizzo legale? Se entrambi sono equivalenti, quale dovrei usare? Devo utilizzare i qualificatori noexcept in questo scenario? Il problema è che indipendentemente dal fatto che le funzioni vector generino il lancio dipende in ogni caso da Tuple.

+0

Vorrei notare che [c'è stata una domanda riguardante l'uso delle variabili membro all'interno di una specifica 'noxcept'] (http://stackoverflow.com/questions/27241938/noexcept-depending-on-method-of -member) qui sulla lavagna, ma tieni presente che questa domanda è correlata a C++ 11 e un errore del compilatore generato da (qualche versione sconosciuta di) clang. – 0xbadf00d

risposta

5

Clang è corretto qui, questo è un bug gcc. Secondo [basic.scope.class], sottolineatura mia:

Il potenziale portata di un nome dichiarato in una classe consiste non solo della regione dichiarativa seguente punto di dichiarazione del nome , ma anche di tutti i corpi di funzione, gli argomenti di default, eccezione -specifiche e iniziatori brace-or-equal- di membri di dati non statici in tale classe (compresi tali elementi nelle classi nidificate ).

Il campo di applicazione comprende la m_elementsnoexcept-specifica per size().