clang / llvm 3.6.2では、次のコードを使用してコンパイルすると、コンパイルエラーが発生しますstd=c++11
。
template <typename T=void>
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar<> b;
return b.baz();
}
コマンドライン呼び出し:
$ clang++ -std=c++11 nonstatic.cpp -o nonstatic
nonstatic.cpp:12:28: error: invalid use of non-static data member 'array'
return sizeof(foo::array);
~~~~~^~~~~
nonstatic.cpp:20:14: note: in instantiation of member function
'bar<void>::baz' requested here
return b.baz();
bar
のように、テンプレートではなくなった場合
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar b;
return b.baz();
}
その後、コードはきれいにコンパイルされます。注目すべきことに、GCC5.2.1はstd=c++11
。の下の両方のバージョンを受け入れます。また、array
それを囲むクラステンプレート本体に移動すると(ただし、テンプレートとして残す)、clangはこれを受け入れます。
標準に対して正しい動作はどれですか?これはGCC、clang、またはその両方のバグですか?
これは確かにclangのバグです。あなたのオペランドsizeof
式であるID-発現非静的データメンバーを表すので、[expr.prim.general] / 13が成り立ちます。縮小した例を次に示します。
template<class T> struct M { int f() { return sizeof(T::x); } };
struct S { int x; };
int main() { return M<S>{}.f(); }
このバグは、テンプレートインスタンスメソッド内の未評価のコンテキストで依存型メンバーにアクセスすると発生します。未評価のコンテキストで非静的データメンバーの使用を可能にするn2253ルールのClangの実装(およびその後の改善)は、かなり壊れやすく、テンプレートとの相互作用が悪いように見えます。同様の(明確ではありますが)バグはhttp://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151019/141535.htmlです。
これがすでにClangBugzillaに報告されているという兆候は見つかりません。新しいバグを開くことをお勧めします。
状況に応じて、回避策には、静的型と値の計算をインスタンスメソッドの外に移動することが含まれる場合があります。特にbaz
、static
メンバー関数を作成するだけでも、clangにコードを受け入れるように説得するのに十分です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加