Saya telah bekerja untuk sementara dalam menjaga tingkat kompatibilitas ke depan dan ke belakang dalam program C ++ saya, sampai akhirnya saya harus membuat toolkit perpustakaan dari itu , yang saya siapkan untuk rilis sudah dirilis. Secara umum, selama Anda menerima bahwa Anda tidak akan mendapatkan kompatibilitas ke depan "sempurna" baik dalam fitur (beberapa hal tidak dapat ditiru) tidak dalam sintaks (Anda mungkin harus menggunakan makro, ruang nama alternatif untuk beberapa hal) maka Anda sudah siap.
Ada banyak fitur bagus yang dapat ditiru di C ++ 03 pada level yang cukup untuk penggunaan praktis - dan tanpa semua kerumitan yang datang dengan mis .: Boost. Heck, bahkan proposal standar C ++ untuk nullptr
menyarankan backport C ++ 03. Dan kemudian ada TR1 misalnya untuk semuanya C ++ 11-tetapi-kita-sudah-pratinjau-selama-tahun hal. Tidak hanya itu, beberapa fitur C ++ 14 seperti varian tegas, functors transparan dan optional
dapat diimplementasikan di C ++ 03!
Hanya dua hal yang saya tahu yang tidak dapat sepenuhnya didukung adalah template constexpr dan variadic.
Berkenaan dengan seluruh masalah menambahkan barang ke namespace std
, pandangan saya tentang hal itu adalah tidak masalah - sama sekali. Pikirkan Boost, salah satu pustaka C ++ yang paling penting dan relevan, dan implementasinya TR1: Boost.Tr1. Jika Anda ingin meningkatkan C ++, buat itu maju kompatibel dengan C ++ 11, maka menurut definisi Anda mengubahnya menjadi sesuatu yang bukan C ++ 03, jadi memblokir diri Anda sendiri atas Standar yang ingin Anda hindari atau tinggalkan. , sederhananya, kontraproduktif. Puritan akan mengeluh, tetapi menurut definisi orang tidak perlu peduli tentang mereka.
Tentu saja, hanya karena Anda tidak akan mengikuti (03) Standar setelah semua tidak berarti Anda tidak dapat mencoba, atau akan dengan senang hati berkeliling melanggar itu. Itu bukan intinya. Selama Anda tetap sangat berhati-hati mengontrol apa yang ditambahkan ke std
namespace, dan memiliki kontrol terhadap lingkungan tempat perangkat lunak Anda digunakan (mis .: lakukan pengujian!), Seharusnya tidak ada bahaya yang tidak dapat dilanggar sama sekali. Jika memungkinkan, tentukan semuanya dalam namespace yang terpisah dan hanya tambahkan using
arahan ke namespace std
sehingga Anda tidak menambahkan apa pun di luar apa yang "mutlak" perlu masukkan. Yang, IINM, kurang lebih seperti yang dilakukan Boost.TR1.
Pembaruan (2013) : sebagai permintaan pertanyaan asli dan melihat beberapa komentar yang tidak dapat saya tambahkan karena kurangnya rep, berikut adalah daftar fitur C ++ 11 dan C ++ 14 dan tingkat portabilitasnya ke C ++ 03:
nullptr
: sepenuhnya dapat dilaksanakan mengingat dukungan resmi Komite; Anda mungkin harus memberikan beberapa spesialisasi type_traits juga sehingga dikenali sebagai tipe "asli".
forward_list
: sepenuhnya dapat diterapkan, meskipun dukungan pengalokasi bergantung pada apa yang dapat diberikan oleh implementasi Tr1 Anda.
- Algoritma baru (partition_copy, dll): sepenuhnya dapat diterapkan.
- Konstruksi kontainer dari brace-sequence (mis .
vector<int> v = {1, 2, 3, 4};
: .:) : sepenuhnya dapat diterapkan, meskipun lebih banyak daripada yang diinginkan.
static_assert
: hampir-sepenuhnya diimplementasikan ketika diimplementasikan sebagai makro (Anda hanya harus berhati-hati dengan koma).
unique_ptr
: hampir-sepenuhnya dapat diterapkan, tetapi Anda juga akan memerlukan dukungan dari kode panggilan (untuk menyimpannya dalam wadah, dll); lihat di bawah ini sekalipun.
- rvalue-reference: hampir dapat diimplementasikan sepenuhnya tergantung pada berapa banyak yang Anda harapkan dari mereka (misalnya: Boost Move).
- Iterasi Foreach: hampir sepenuhnya dapat diimplementasikan, sintaks akan sedikit berbeda.
- menggunakan fungsi lokal sebagai argumen (misalnya transformasi:): hampir sepenuhnya dapat diimplementasikan, tetapi sintaksis akan cukup berbeda - misalnya, fungsi lokal tidak didefinisikan di situs panggilan tetapi tepat sebelumnya.
- operator konversi eksplisit: dapat diterapkan ke level praktis (membuat konversi dibuat eksplisit), lihat "eksplisit_cast" Imperfect C ++ ; tetapi integrasi dengan fitur bahasa seperti
static_cast<>
mungkin hampir mustahil.
- penerusan argumen: dapat diterapkan ke tingkat praktis yang diberikan di atas pada rvalue-referensi, tetapi Anda harus memberikan N kelebihan pada fungsi Anda mengambil argumen yang dapat diteruskan.
- move: dapat diterapkan ke level praktis (lihat dua hal di atas). Tentu saja, Anda harus menggunakan wadah pengubah dan benda untuk mendapatkan keuntungan dari ini.
- Alokasi pengalokasi: Tidak benar-benar dapat diimplementasikan kecuali implementasi Tr1 Anda dapat membantunya.
- tipe karakter multibyte: Tidak benar-benar dapat diterapkan kecuali Tr1 Anda dapat mendukung Anda. Tetapi untuk tujuan yang dimaksud lebih baik mengandalkan perpustakaan yang dirancang khusus untuk menangani masalah ini, seperti ICU, bahkan jika menggunakan C ++ 11.
- Daftar argumen variadik: dapat diterapkan dengan sedikit kerumitan, perhatikan penerusan argumen.
noexcept
: tergantung pada fitur kompiler Anda.
- New
auto
semantik dan decltype
: tergantung pada fitur compiler Anda - misalnya .: __typeof__
.
- tipe integer berukuran (
int16_t
, dll): tergantung pada fitur kompiler Anda - atau Anda dapat mendelegasikan ke Portable stdint.h.
- ketik atribut: tergantung pada fitur kompiler Anda.
- Daftar Initializer: Tidak dapat diterapkan untuk pengetahuan saya; namun jika yang Anda inginkan adalah menginisialisasi kontainer dengan urutan, lihat di atas pada "konstruksi kontainer".
- Aliasing Templat: Tidak dapat diaplikasikan pada pengetahuan saya, tetapi itu adalah fitur yang tidak dibutuhkan, dan kami sudah memiliki
::type
templat selamanya
- Templat variadik: Tidak dapat diterapkan untuk pengetahuan saya; penutupnya adalah argumen templat defaulting, yang membutuhkan N spesialisasi, dll.
constexpr
: Tidak dapat diterapkan untuk pengetahuan saya.
- Inisialisasi seragam: Tidak dapat diterapkan untuk pengetahuan saya, tetapi inisialisasi default -constructor yang dijamin dapat diimplementasikan dengan nilai Boost yang diinisialisasi.
- C ++ 14
dynarray
: sepenuhnya dapat diterapkan.
- C ++ 14
optional<>
: hampir sepenuhnya diimplementasikan asalkan kompiler C ++ 03 Anda mendukung pengaturan perataan.
- C ++ 14 functors transparan: hampir sepenuhnya diimplementasikan, tetapi kode klien Anda mungkin harus secara eksplisit menggunakan mis .:
std::less<void>
untuk membuatnya berfungsi.
- C ++ 14 varian menegaskan baru (seperti
assure
): sepenuhnya dapat diterapkan jika Anda ingin menegaskan, hampir sepenuhnya dapat diterapkan jika Anda ingin mengaktifkan lemparan sebagai gantinya.
- C ++ 14 ekstensi tuple (dapatkan elemen tuple berdasarkan tipe): sepenuhnya dapat diterapkan, dan Anda bahkan bisa membuatnya gagal untuk dikompilasi dengan kasus-kasus persis yang dijelaskan dalam proposal fitur.
(Penafian: beberapa fitur ini diimplementasikan di pustaka C ++ backports saya yang saya tautkan di atas, jadi saya pikir saya tahu apa yang saya bicarakan ketika saya mengatakan "sepenuhnya" atau "hampir sepenuhnya".)