12

いくつかのコードをMSVCに移植する際に問題が発生し、困惑しました。私の知る限り、コードは合法である必要があり、Clangはそれを問題なくコンパイルします。

私はそれを以下に絞り込みました:

enum E {
    x
};

template <typename T>
struct traits {
    static const E val = x;
};

template <E e>
struct S {
    S(){};
};

template <typename T>
S<traits<T>::val> foo(T t);

int main() {
    char c = 0;
    foo(c);
}

fooコンパイル後、コードはリンカーエラーを生成することが予想されますが(サンプルを最小限に抑えるために関数の定義を削除しました)、私が知る限り、コードはクリーンにコンパイルされるはずです。

ただし、MSVCでは次のエラーが発生します。

エラーC2893:関数テンプレート'S :: val> foo(T)'の特殊化に失敗しました

だから私の質問:

  • MSVCは、コードを拒否する際に万が一正しいですか?(もしそうなら、なぜですか?)
  • そうでない場合、誰かがそれが間違っていることを絞り込むことができますか?のように、それは彼らがまったく実装していない言語機能(テンプレートの2フェーズの名前検索など)ですか、それとも彼らがサポートしていると主張する機能の実装における単なるバグですか?

VC++2010および2012で問題を再現しました。

4

1 に答える 1

3

自分でいくつかのテストを実行した後、これは MSVC のコンパイラ バグのようです。traits<T>::valGCC では問題なく動作しますが、戻り値のテンプレート パラメーター内で使用しようとすると、MSVC は不可解で役に立たないコンパイラ エラー (質問のものと同じ) をS< E e >返します。

面白いことに、S< E e >代わりに整数を取るように変更すると、機能します。次の例を考えてみてください。これは、名前が異なるものと同じです。

enum E {
    x
};

template <typename T>
struct traits {
    static const E val = x;
};

template <E e>
struct S {
    S(){};
};

template <typename T>
S< traits<T>::val > tricky(T t) {
    return S< traits<T>::val > ();
};

int main() {
    char thiskidwhowalksaround = 0;
    S<x> s = tricky( thiskidwhowalksaround );
}

では、 1 つだけ変更してみましょう。

template <int e> // int instead of E
struct S {
    S(){};
};

その後、プログラムは問題なくコンパイル (リンクおよび実行) されます。また、元に戻してから、値をE直接渡すと、次のようになります。

template <typename T>
S< x > tricky(T t) { 
// ^ here
    return S< x > (); // <-- here
};

次に、プログラムはファイルをコンパイルします。MSVC には、次のことを行おうとすると失敗するという問題があります。

traits<T>::val

wherevalはあらゆる種類の列挙型です。これはコンパイラ自体の欠陥であると 99% 確信しています。これは完全に整形式の C++ のように見えるので、元のコード スニペットが機能することで、GCC が何か間違ったことや拡張機能を行っているとは言えません。したがって、私が収集できる最善のことは、MSVC は同業他社と比較してコンパイラの堅牢性に欠けているということです。

ここで読むのをやめてもかまいません。ここで、MSVC コンパイラについて怒鳴る時間をとります。

begin<rant> VC++ チームが悪いとか C++ が悪いというわけではありませんが、私が収集したところによると、Microsoft のコンパイラ チームと標準ライブラリ チームは (執筆時点では)他の部門に比べて小規模です。このような基本的かつ重要な言語であり、MS 業界の中核の一部である言語が、比較的人員が少なく、私の短い人生の中で、世界で最も動きの遅い標準の 1 つであることに追いつくことができないことに腹を立てています。私は確かに VC++ チームで働いている個人をノックアウトしているわけではありませんが、C++ を高速化するだけでなく、コンパイラーを他のものと同じようにより良く機能させることに取り組んでいる人が増えていない理由について、私は非常に当惑しています。製品エリア。 end<rant>

于 2013-03-17T22:23:41.020 に答える