gcc 5.0 と clang 3.6 の両方typename
で、次の例のキーワードが必要です。
template<typename T>
struct B
{
typedef int Type;
};
template<int n>
struct A
{
typedef typename B<decltype(throw (int*)n)>::Type Throw;
typedef typename B<decltype(delete (int*)n)>::Type Delete;
};
これは、C++11 標準の次の文言でカバーされています。
[除く]/2
throw 式は void 型です。
[expr.delete]/1
オペランドには、オブジェクト型へのポインター、またはオブジェクト型へのポインターへの単一の非明示的な変換関数を持つクラス型が必要です。結果の型は void です。
したがって、両方のケースでdecltype
生成されると想定しています。void
[expr.const]/2
conditional-expression は、潜在的に評価される部分式として次のいずれかを含まない限り、コア定数式です。
新しい式
スロー式
throw
これは、またはのいずれかを含む式がdelete
定数式ではないことを示唆しています。
[温度依存タイプ]/8
ある場合、型は従属です。
テンプレート名がテンプレート パラメータであるか、いずれかのテンプレート引数が依存型または型依存または値依存の式である simple-template-id
で表され
decltype(expression)
、式は型に依存します
SoB<decltype(..)>
は、式が型依存の場合にのみ依存します。
[温度.dep.expr]/4
次の形式の式は型に依存しません (式の型は依存できないため)。
delete cast-expression throw assignment-expression
これは、どちらの式も型に依存しないことを示唆しています。
gcc と clang はどちらも間違っていますか?