Apakah program berikut ini terbentuk dengan baik?
#include <vector>
struct A {
explicit A(int) {}
};
int main() {
std::vector<int> vi = {1, 2, 3, 4, 5};
std::vector<A> va(vi.begin(), vi.end());
}
Menurut C ++ 17 [sequence.reqmts], persyaratan untuk
X u(i, j);
di mana X
adalah wadah urutan, adalah:
T
akanEmplaceConstructible
menjadiX
dari*i
.
Namun, dalam paragraf sebelumnya dinyatakan bahwa:
i
danj
menunjukkan iterator yang memenuhi persyaratan input iterator dan merujuk pada elemen yang secara implisit dapat dikonversi kevalue_type
,
Jadi menurut saya kedua persyaratan tersebut harus dipenuhi: tipe nilai dari rentang harus secara implisit dapat dikonversi ke tipe nilai kontainer, dan EmplaceConstructible
harus dipenuhi (yang berarti pengalokasi harus dapat melakukan inisialisasi yang diperlukan) . Karena int
tidak secara implisit dikonversi ke A
, program ini harus dibuat dengan buruk.
Namun, yang mengejutkan, sepertinya dikompilasi di bawah GCC .
Jawaban:
Ini hanya persyaratan untuk wadah urutan untuk mendukung konstruksi dari iterator yang memenuhi kriteria konvertibilitas implisit.
Ini tidak dengan sendirinya melarang kontainer berurutan untuk mendukung konstruksi dari iterator yang tidak memenuhi kriteria sejauh yang saya tahu 1 . Ada aturan eksplisit tentang itu:
Tidak jelas apa "memenuhi syarat sebagai input iterator" berarti persis dalam konteksnya. Apakah ini cara informal untuk mengekspresikan Cpp17InputIterator, atau apakah ia mencoba merujuk persyaratan i dan j? Saya tidak tahu Apakah diizinkan atau tidak, standar tidak memiliki persyaratan ketat untuk mendeteksinya:
Dengan interpretasi bahwa setiap Cpp17InputIterator "memenuhi syarat sebagai input iterator", program contoh tidak akan diminta untuk dibentuk dengan buruk. Tapi itu tidak dijamin akan terbentuk dengan baik.
1 Dalam kasus seperti itu, ini mungkin dianggap sebagai kualitas masalah implementasi untuk diperingatkan ketika mengandalkannya. Di sisi lain, pembatasan konversi implisit ini dapat dianggap sebagai cacat .
PS Ini mengkompilasi tanpa peringatan di Dentang (dengan libc ++) dan Msvc juga.
PPS Kata-kata ini tampaknya telah ditambahkan dalam C ++ 11 (yang alami, seperti yang juga konstruktor eksplisit juga diperkenalkan).
sumber
Cpp17InputIterator
, jadi tidak jelas bagi saya apakah "dan merujuk pada elemen yang secara implisit dapat dikonversi menjadivalue_type
" termasuk dalam "input iterator". Jika ya, maka konstruktor tidak boleh berpartisipasi dalam resolusi kelebihan beban dan program harus dibentuk dengan buruk.Cpp17InputIterator
, atau apakah ia mencoba merujuk pada persyaratani
danj
? Saya tidak tahu