Kemungkinan kompiler bug di MSVC

13

Kode berikut dikompilasi dengan gcc dan dentang (dan banyak kompiler C ++ 11 lainnya)

#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};
}

saat dikompilasi dengan (hampir) MSVC terbaru

> 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

Apakah ini bug dari MSVC? Jika ya, istilah mana dalam standar C ++ yang paling tepat menggambarkannya?

Jika Anda mengganti bagian dari kode dengan

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

itu mengkompilasi dengan lancar pula.

Awan
sumber
Satu kalimat ini mungkin menjelaskan perbedaannya. Lihat untuk apa kompiler Anda kembali std::is_same_v<char, int8_t>. Dugaan saya adalah implementasi didefinisikan apakah int8_t sama dengan char, tetapi orang perlu memeriksa dokumentasi.
ubah igel
Sepertinya itu sebenarnya bug. Masalah ini dibuka baru-baru ini dan ada beberapa laporan lainnya.
diubah diubah
1
@alteredinstance Saya tidak melihat bagaimana masalah itu terkait dengan pertanyaan ini, atau bagaimana tautan Anda sebelumnya, dalam hal ini. Apakah Anda baru menyalin tautan pertama yang diberikan Google untuk pesan kesalahan ini? Pesan kesalahan sangat umum dan dapat muncul dalam berbagai situasi (yang sah).
walnut
@walnut Line 231 dari kode yang disebutkan dalam masalah ini memiliki tautan mati ke masalah MSVC dengan inisialisasi agregat, hal yang sama dilakukan oleh kode OP. Kebetulan bahwa boost library baru-baru ini mengalami masalah yang sama dengan penggunaan valuedalam tipe agregat dengan MSVC
alteredinstance

Jawaban:

8

Saya akan mengatakan MSVC salah karena tidak menerima kode.

Menurut [dcl.fct.default] / 5 dari draft final standar C ++ 17, pencarian nama dalam argumen default fungsi anggota templat kelas dilakukan sesuai dengan aturan di [temp.inst].

Menurut [temp.inst] / 2 instantiasi implisit dari templat kelas tidak menyebabkan instantiasi argumen default dari fungsi anggota dan menurut [temp.inst] / 4 argumen default untuk fungsi anggota dari (spesialisasi non-eksplisit dari a) template kelas dipakai saat digunakan oleh panggilan.

Tidak ada panggilan menggunakan argumen default to_datatype<T>::valuedalam kode Anda dan karenanya tidak boleh dipakai. Oleh karena itu tidak boleh ada kesalahan tentang pencarian dari valuedalam to_datatype<char>gagal.

(Bagian yang relevan dalam draft final standar C ++ 11 memiliki susunan kata yang setara, kecuali untuk penomoran, lihat [decl.fct.default] / 5 , [temp.inst] / 1 dan [temp.inst] / 3 sebagai gantinya.)

kenari
sumber