2016-03-08 11 views
7

次のコードスニペットを考えてみてください: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; 
} 

は法的noexcept指定内部メンバ変数m_elementsの使用ですか? GCC 5.2 (C++17) yields the compiler errorm_elementsこのスコープでは宣言されていませんclang 3.6 (C++17) compiles without any error

代わりにnoexcept(std::declval<Tuple const&>().size())を使用すると、両方のコンパイラでエラーが発生しません。しかし、わかりましたが、tupleという簡単なサンプルクラスを作成しました。Tupleには、修飾されたオーバーロードがsizeであるかどうかが重要です。私の視点から

が、それは関数本体で正確に呼び出しの原因noexcept(m_elements.size())を書くために、より直感的だし、vectorsize方法は以下の範囲にm_elements constオブジェクトを作る資格const(で考慮されます関数)。

だから、法的な用法は何ですか?どちらも同等の場合は、どちらを使用しますか?このシナリオではnoexcept修飾子を使用する必要がありますか?問題は、vectorの機能がスローされるかどうかは、ほとんどすべてのケースでTupleに依存するということです。

+0

私は[noexcept'仕様の中のメンバー変数の使用に関する質問がありました](http://stackoverflow.com/questions/27241938/noexcept-depending-on-method-of -member)を掲示板に載せていますが、この質問はC++ 11と、(未知のバージョンの)clangによって生成されたコンパイラエラーに関連しています。 – 0xbadf00d

答えて

5

ここではClangが正しくあります。これはgccバグです。 [basic.scope.class]によると、強調鉱山は:

クラスで宣言された名前の潜在的な範囲だけではなく、宣言の 名前のポイント以下の宣言型領域からなる、だけでなく、すべての関数本体の、デフォルト引数、例外クラス クラス内のそのようなものを含めて、およびブレースまたは同等イニシャライザの非静的データメンバーが含まれています。

m_elementsの範囲はsize()ためnoexcept仕様を含みます。

関連する問題