Apakah ada cara untuk mendeteksi pada waktu kompilasi jika kompilator mendukung fitur tertentu C ++ 11? Misalnya, seperti ini:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
template <typename... Test> struct compiler_must_support_variadic_templates;
. Kesalahan sintaksis akan segera mengungkap masalahnya. (Selain itu, pesan kesalahan yang tepat jauh lebih baik.)Jawaban:
Ada konstanta bernama
__cplusplus
yang harus disetel oleh compiler C ++ ke versi standar C ++ yang didukung. Lihat iniIni diatur ke 199711L dalam Visual Studio 2010 SP1, tetapi saya tidak tahu apakah vendor akan begitu berani untuk meningkatkannya jika mereka hanya memiliki (sebagian) dukungan tingkat kompiler versus pustaka C ++ standar dengan semua perubahan C ++ 11 .
Jadi definisi Boost yang disebutkan dalam jawaban lain tetap menjadi satu-satunya cara yang masuk akal untuk mengetahui apakah ada, misalnya, dukungan untuk utas C ++ 11 dan bagian spesifik lainnya dari standar.
sumber
__cplusplus
menjadi201103L
. Itu menegaskan kesesuaian penuh dengan standar 2011; itu tidak memberi tahu Anda tentang kesesuaian parsial atau ekstensi kompilator. Jika__cplusplus
disetel ke201103L
, maka kompilator sepenuhnya sesuai atau berbohong kepada Anda. Jika tidak, maka Anda tidak dapat benar-benar mengetahui fitur mana yang didukungnya.-std=c++11
opsi ditentukan (mungkin juga dengan-std=gnu++11
). Mereka melakukan ini, meskipun fitur mereka belum cukup lengkap (4.8 membawa kita lebih dekat). Catatan - ada celah antara apa yang didukung kompilator dan yang tersedia di pustaka standar. Baik 4.7.x & 4.8.x saat ini tidak memiliki dukungan regex - tetapi itu adalah pustaka, bukan fitur kompiler.__cplusplus
menjadi199711L
untuk C ++ 11.__cplusplus
untuk199711L
tidak sesuai C ++ 11 compiler. Mereka mungkin memiliki opsi untuk membuat mereka berperilaku dengan benar.Seperti yang dinyatakan oleh standar C ++ 11 (§iso.16.8):
Dengan nilai makro itu, Anda dapat memeriksa apakah kompilernya sesuai dengan C ++ 11.
Sekarang, jika Anda mencari cara standar untuk memeriksa apakah kompiler mendukung subset fitur C ++ 11, saya rasa tidak ada cara standar dan portabel; Anda dapat memeriksa dokumentasi kompiler atau file header perpustakaan std untuk mendapatkan informasi lebih lanjut.
sumber
Saya tahu bahwa ini adalah pertanyaan yang sangat lama, tetapi pertanyaan ini mungkin sering terlihat, dan jawabannya agak ketinggalan zaman.
Compiler baru dengan standar C ++ 14 memiliki cara standar untuk memeriksa fitur, termasuk fitur C ++ 11. Halaman lengkapnya ada di https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
Singkatnya, setiap fitur memiliki makro standar yang ditentukan yang dapat Anda periksa
#ifdef
. Misalnya, untuk memeriksa literal yang ditentukan pengguna, Anda dapat menggunakansumber
__has_include()
makro.Untuk memeriksa dukungan C ++ 14 dan lainnya. Pengujian di GCC 5.2.1.
sumber
Anda dapat menggunakan ini:
Untuk C ++ 11, sebagian besar kompiler kecuali Visual Studio menetapkan
__cplusplus
makro201103L
, tetapi versi Visual Studio mana pun menetapkannya di199711L
mana nilai yang digunakan untuk kompiler lain sebelum C ++ 11. Kode ini membandingkan_cplusplus
makro dengan201103L
untuk semua kompiler kecuali Visual Studio, dan jika kompilernya adalah Visual Studio, ia memeriksa apakah versi Visual Studio lebih lambat dari 2015, versi pertama Visual Studio yang sepenuhnya mendukung C ++ 11 (untuk Visual Studio 2015,_MSC_VER
makro memiliki nilai1900
, lihat jawaban ini ).sumber
g++ -std=c++98
dengan GCC 4.8, pencetakannya salahC++11 is supported
.Jika Anda tidak ingin menggunakan Boost.Config dan perlu menguji kompiler yang mendukung C ++ 11, maka memeriksa nilai konstanta
__cplusplus
akan dilakukan. Namun, kompiler mungkin mendukung sebagian besar fitur populer dari standar C ++ 11 namun tidak mendukung seluruh spesifikasi. Jika Anda ingin mengaktifkan dukungan untuk kompiler Visual Studio tertentu yang belum 100% sesuai dengan spesifikasi C ++ 11, gunakan potongan kode berikut yang memungkinkan kompilasi di Visual Studio 2013:Daftar lengkap versi kompiler untuk Visual Studio tersedia di cara mendeteksi jika saya sedang menyusun kode dengan Visual Studio 2008
sumber
Di dunia Linux / Unix tradisional, autoconf secara tradisional digunakan untuk menguji keberadaan pustaka dan fitur kompilator dan bug menempatkannya ke dalam config.h yang Anda gunakan di file sesuai kebutuhan.
sumber
Jika pemeriksaan Anda adalah untuk ketersediaan pustaka C ++ 11 (bukan fitur bahasa), misalnya
<array>
header, Anda bisa#if __has_include(<array>)
.Terkadang pemeriksaan
#if __cplusplus >= 201103L
akan memberi tahu Anda bahwa Anda menggunakan C ++ 11 tetapi pengaturan lain seperti pengaturan versi perpustakaan standar di Xcode mungkin masih tidak memiliki perpustakaan baru yang tersedia (kebanyakan dari mereka tersedia dalam nama yang berbeda yaitu<tr1/array>
)sumber