C ++ 11 desteğini nasıl kontrol ederim?


104

Derleyici C ++ 11'in belirli özelliklerini destekliyorsa, derleme zamanında algılamanın bir yolu var mı? Örneğin, bunun gibi bir şey:

#ifndef VARIADIC_TEMPLATES_SUPPORTED

#error "Your compiler doesn't support variadic templates.  :("

#else

template <typename... DatatypeList>
class Tuple
{
    // ...
}

#endif

2
"Assert_variadic_template_support.hpp" adında dahil edebileceğiniz ve buna benzer bir şey yapabileceğiniz bir başlığınız olabilir template <typename... Test> struct compiler_must_support_variadic_templates;. Bir sözdizimi hatası sorunu hızla ortaya çıkarır. (Bir kenara olarak, uygun bir hata mesajı çok daha iyidir.)
— GManNickG

Bu sorunu çözmenin 'doğru' yolu bir yapılandırma testidir.
— Joseph Garvin

Yanıtlar:


125

__cplusplusC ++ derleyicilerinin desteklenen C ++ standardının sürümüne ayarlaması gereken bir sabit var, bkz.

#if __cplusplus <= 199711L
  #error This library needs at least a C++11 compliant compiler
#endif

Visual Studio 2010 SP1'de 199711L olarak ayarlandı, ancak satıcıların, tüm C ++ 11 değişikliklerini içeren standart bir C ++ kitaplığına karşılık (kısmi) derleyici düzeyinde desteğe sahip olmaları durumunda, bunu şimdiden artırmak için bu kadar cesur olup olmayacaklarını bilmiyorum. .

Dolayısıyla, başka bir yanıtta bahsedilen Boost'un tanımları, örneğin C ++ 11 iş parçacıkları ve standardın diğer belirli bölümleri için destek olup olmadığını anlamanın tek mantıklı yolu olmaya devam ediyor.


37
C ++ 11 setleri değeri __cplusplusiçin 201103L. Bu, 2011 standardına tam uyumu gösterir; size kısmi uyumluluk veya derleyici uzantıları hakkında bilgi vermez. Olarak __cplusplusayarlanmışsa 201103L, derleyici ya tamamen uyumludur ya da size yalan söylüyor. Değilse, hangi özellikleri desteklediğini gerçekten söyleyemezsiniz.
— Keith Thompson

1
g ++ 4.7.x (ve muhtemelen daha yeni), -std=c++11seçenek belirtildiğinde (ile de olabilir ) bunu ayarlar -std=gnu++11. Özellik tam olarak tamamlanmasalar bile bunu yaparlar (4.8 bizi çok daha yakınlaştırır). Not - derleyicinin desteklediği ile standart kitaplıkta bulunanlar arasında bir boşluk vardır. Hem 4.7.x hem de 4.8.x şu anda normal ifade desteğinden yoksundur - ancak bu bir kitaplık, bir derleyici özelliği değil.
— Nathan Ernst

1
Bunun neden kabul edilen cevap olmadığını merak ediyorum. Ayrıca, cevabınızı daha da iyileştirmek için bu öneriyi kullanabilirsiniz , çok iyi.
— Iharob Al Asimi

1
@KeithThompson Benim için ikisi de Code :: Blocks ve Visual Studio değerini ayarlamak __cplusplusiçin 199711LC ++ 11 için
— Donald Duck

3
@DonaldDuck: Kesinlikle, hayır, yapmıyorlar. Bir derleyici o setleri __cplusplusiçin 199711Lbir uyumlu C ++ 11 derleyici değildir. Muhtemelen doğru davranmalarını sağlayacak seçenekleri vardır.
— Keith Thompson

39

C ++ 11 standardında belirtildiği gibi (§iso.16.8):

__Cplusplus adı , bir C ++ çeviri birimi derlenirken 201103L değeri olarak tanımlanır .

Bu makronun değeri ile derleyicinin C ++ 11 uyumlu olup olmadığını kontrol edebilirsiniz.

Şimdi, derleyicinin C ++ 11 özelliklerinin herhangi bir alt kümesini destekleyip desteklemediğini kontrol etmenin standart bir yolunu arıyorsanız, standart, taşınabilir bir yol olmadığını düşünüyorum; Daha fazla bilgi almak için derleyici belgelerine veya std kitaplık başlık dosyalarına bakabilirsiniz.


2
Örneğin, static_assert VS2010 ve tüm c ++ 11 kopyalayıcılarında desteklenir. Yani, __cplusplus değerinin VS2010'da ayarlanandan daha büyük veya ona eşit olup olmadığını kontrol ederseniz (yani> = 199711L), iyi olabilirsiniz.
— Paolo M

33

Bunun çok eski bir soru olduğunu biliyorum, ancak bu soru sıklıkla görülebilir ve cevapları biraz güncel değil.

C ++ 14 standardına sahip daha yeni derleyiciler, C ++ 11 özellikleri dahil olmak üzere özellikleri denetlemek için standart bir yola sahiptir. Kapsamlı bir sayfa https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations adresindedir.

Özetle, her özelliğin kontrol edebileceğiniz standart bir makro tanımlanmıştır #ifdef. Örneğin, kullanıcı tanımlı değişmez değerleri kontrol etmek için kullanabilirsiniz

#ifdef __cpp_user_defined_literals

1
Bunu bilmiyordum. Bu basit özelliğin geç geleceğini düşünüyorum, ancak yine de çok faydalı olabilir, özellikle __has_include()makro.
— prapin

22

Kontrol desteği için C ++ 14 ve diğer. GCC 5.2.1 üzerinde test etme.

#include <iostream>

int main(){
        #if __cplusplus==201402L
        std::cout << "C++14" << std::endl;
        #elif __cplusplus==201103L
        std::cout << "C++11" << std::endl;
        #else
        std::cout << "C++" << std::endl;
        #endif

        return 0;
}

17

Bunu kullanabilirsiniz:

#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
    cout << "C++11 is supported";
#else
    cout << "C++11 is not supported";
#endif

C ++ 11 için, Visual Studio dışındaki çoğu derleyici __cplusplusmakroyu olarak 201103Layarlar, ancak Visual Studio'nun herhangi bir sürümü onu, 199711LC ++ 11'den önce diğer derleyiciler için kullanılan değerde ayarlar . Bu kod, Visual Studio dışındaki tüm derleyiciler için _cplusplusmakroyu karşılaştırır ve 201103Lderleyici Visual Studio ise, Visual Studio sürümünün C ++ 11'i tamamen destekleyen ilk sürümü olan 2015'ten sonra olup olmadığını denetler (Visual Studio için Studio 2015, _MSC_VERmakronun değeri var 1900, bu cevaba bakın ).


1
Bu cevap yanlıştır. İçin g++ -std=c++98GCC 4.8, yanlış basar C++11 is supported.
— pts

1
@pts Üzgünüz, sadece bir yazım hatası. Şimdi düzeltilmesi gerekiyor.
— Donald Duck

7

Boost.Config'i kullanmak istemiyorsanız ve C ++ 11'i destekleyen derleyicileri test etmeniz gerekiyorsa, sabitin değerini kontrol etmek yeterli __cplusplusolacaktır. Ancak, bir derleyici C ++ 11 standardının popüler özelliklerinin çoğunu destekleyebilir, ancak tüm özellikleri desteklemez. Henüz C ++ 11 belirtimlerine% 100 uyumlu olmayan belirli Visual Studio derleyicileri için desteği etkinleştirmek istiyorsanız, Visual Studio 2013'te derlemeye izin veren aşağıdaki kod parçacığını kullanın:

#if defined(_MSC_VER)
#   if _MSC_VER < 1800 
#       error This project needs atleast Visual Studio 2013
#   endif
#elif __cplusplus <= 199711L
#   error This project can only be compiled with a compiler that supports C++11
#endif

Visual Studio için derleyicinin tam bir listesi, Visual Studio 2008 ile Kod Derliyor muyum?


6

Geleneksel Linux / Unix dünyasında, autoconf geleneksel olarak kitaplıkların ve derleyici özelliklerinin varlığını test etmek için kullanılır ve bunları gerektiğinde dosyalarınızda kullandığınız bir config.h'ye yerleştirir.


2
Evet autoconf, özellikleri test etmek için kullanılabilir, ancak daha sonra yukarıdaki kodla test edilebilecek, başarısızlık veya başarılar için uygun makroyu oluşturmasını sağlamalısınız. Yani bu cevap kendi başına hiçbir bilgi eklemiyor.
— Martin York

3
@LokiAstari: autoconf böyle çalışmıyor. Autoconf, configure betiğinizin bir test kaynak dosyası derlemesini ve derlemenin başarısına bağlı olarak #define değerini 0 veya 1 olarak ayarlamanızı sağlayan makrolar sağlar. diverscuba23'ün cevabı, OP'nin gerçek soruna yetersiz bir çözüme ulaştığına işaret ederek bilgi sağlar.
— Joseph Garvin


1

Çekiniz bir C ++ 11 kitaplığının kullanılabilirliği (bir dil özelliği değil), örneğin <array>başlık için olduğunda, bunu yapabilirsiniz #if __has_include(<array>).

Bazen kontrol etmek #if __cplusplus >= 201103Lsize C ++ 11 kullandığınızı söyler, ancak Xcode'daki standart kitaplık sürümü ayarı gibi diğer ayarlarda hala yeni kitaplıklar bulunmayabilir (çoğu farklı adlarda mevcuttur <tr1/array>)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.