MSVCのコンパイラのバグの可能性


13

次のコードは、gccとclang(および他の多くのC ++ 11コンパイラ)でコンパイルされます。

#include <stdint.h>

typedef int datatype;

template <typename T>
struct to_datatype {};

template <>
struct to_datatype<int16_t> {
  static constexpr datatype value = 1;
};

template <typename T>
class data {
 public:
  data(datatype dt = to_datatype<T>::value) {}
};

int main() {
  data<char> d{to_datatype<int16_t>::value};
}

(ほぼ)最新のMSVCでコンパイルする場合

> cl .\test.cpp /std:c++latest /permissive-
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
.\test.cpp(16): error C2039: 'value': is not a member of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(16): note: see declaration of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(20): note: see reference to class template instantiation 'data<char>' being compiled

これはMSVCのバグですか?はいの場合、C ++標準のどの用語がそれを最もよく説明していますか?

コードの一部を

template <typename T>
class data {
 public:
  data(datatype dt) {}
  data() : data(to_datatype<T>::value) {}
};

とにかくスムーズにコンパイルされます。


このワンライナーは違いを説明するかもしれません。コンパイラが何を返すかを確認してくださいstd::is_same_v<char, int8_t>。私の推測では、int8_tがcharと同じであるかどうかは実装で定義されていますが、ドキュメントを確認する必要があります。
igelを

実際にはバグのようです。この問題は最近オープンし、他にもいくつかの報告があります。
インスタンスの変更

1
@alteredinstanceその問題について、その問題がこの質問にどのように関係しているか、または以前のリンクがどのように関係しているかはわかりません。グーグルがこのエラーメッセージに与える最初のリンクをコピーしましたか?エラーメッセージは非常に一般的であり、さまざまな(正当な)状況で表示されます。
ウォールナット

問題で言及されているコードの @walnut 行231には、集計の初期化によるMSVCの問題への無効なリンクがあり、OPのコードと同じことが行われています。たまたま、Boost LibraryがvalueMSVCで集約型を使用する場合に同様の問題に
遭遇しました

回答:


8

MSVCはコードを受け入れないのは間違いだと思います。

C ++ 17標準最終ドラフトの[dcl.fct.default] / 5によると、クラステンプレートのメンバー関数のデフォルト引数での名前の検索は、[temp.inst]のルールに従って行われます。

[temp.inst] / 2によると、クラステンプレートの暗黙的なインスタンス化はメンバー関数のデフォルト引数のインスタンス化を引き起こさず、[temp.inst] / 4によると、(非明示的な特殊化のメンバー関数のデフォルト引数) a)クラステンプレートは、呼び出しで使用されるときにインスタンス化されます。

to_datatype<T>::valueコードにデフォルトの引数を使用する呼び出しはないため、インスタンス化しないでください。したがって、の検索valueto_datatype<char>失敗してもエラーは発生しません。

(C ++ 11標準の最終ドラフトの関連セクションには、番号付けを除いて同等の表現があります。代わりに[decl.fct.default] / 5[temp.inst] / 1および[temp.inst] / 3を参照してください。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.