Aku sedang bermain-main dengan auto
di std::pair
. Dalam kode di bawah ini, fungsi f
seharusnya mengembalikan std::pair
tipe yang bergantung pada parameter templat.
Contoh kerja:
CONTOH 1
template <unsigned S>
auto f()
{
if constexpr (S == 1)
return std::pair{1, 2}; // pair of ints
else if constexpr (S == 2)
return std::pair{1.0, 2.0}; // pair of doubles
else
return std::pair{0.0f, 0.0f}; // pair of floats
}
Ini bekerja dengan gcc 9.2, gcc 10.0, dentang 9.0 dan dentang 10.0.
Selanjutnya, saya ingin secara eksplisit menulis jenis pengembalian sebagai std::pair
alasan kejelasan:
CONTOH 2
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return {1, 2};
/* ... */
}
Baik gcc 9.2 / 10.0 dan clang 9.0 / 10.0 gagal untuk mengkompilasi ini.
gcc 9.2
error: invalid use of 'auto'
error: template argument 1 is invalid // first argument (auto) of std::pair
error: template argument 2 is invalid // second argument (auto) of std::pair
error: cannot convert '<brace-enclosed initializer list>' to 'int' in return
Dari pesan kesalahan terakhir, gcc 9.2 tampaknya percaya itu std::pair<auto, auto>
adalah int
. Bagaimana ini bisa dijelaskan?
gcc 10.0
error: returning initializer list
Kesalahan ini dapat dimengerti, namun, saya berharap konstruktor std::pair
akan dipanggil, atau ada sesuatu yang saya lewatkan di sini?
dentang 9.0 dan 10.0
'auto' not allowed in template argument
excess elements in scalar initializer
no matching function for call to 'f'
Ok, dentang tidak suka semua ini. Dari pesan kesalahan kedua, sepertinya dentang juga percaya tipe kembalinya int
.
Akhirnya, untuk memperbaiki kesalahan yang diperoleh kompilasi dengan gcc 10.0, saya memutuskan untuk mengembalikan secara std::pair
eksplisit:
CONTOH 3
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return std::pair{1, 2};
/* ... */
}
dentang 9.0 dan 10.0
Sama seperti sebelumnya, tetapi dengan tambahan:
no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'
Di sini dentang masih berpikir kita akan mengembalikan int
?
gcc 9.2
Sama seperti sebelumnya.
gcc 10.0
Berhasil!
Saya kira beberapa fitur masih harus diimplementasikan, atau dalam salah satu situasi yang dijelaskan di atas, apakah ada kompiler yang benar dan yang lainnya salah? Menurut pendapat saya, contoh 2 harus bekerja. Atau seharusnya tidak?
auto x = {1, 2};
berfungsi, tetapi hanya jika semua jenisnya sama.int
. Bukan ituint
adalah placeholder dalam pesan kesalahan; kompiler benar-benar berpikir bahwa ini adalahint
. (Untuk memperjelas ini, gcc mungkin seharusnya mengatakan "mengasumsikan int" di beberapa titik.)std::pair __f{1,2};
berfungsi.std::optional f() { return 4; }
bekerja.