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.