Визначення підтримки компілятором особливостей C++

1 хв. читання

Багато років пройшло з моменту появи нових стандартів C++, але досі трапляються системи у яких вони не підтримуються. У цій статті я розкажу, як за допомогою препроцесору визначити, чи підтримує компілятор потрібні мовні нововведення.

__cpluslus

Найбільш "правильним" є використання макросу __cpluslus. Це значення, яке рівне року та місяцю прийняття стандарту у форматі yyyymmL, зокрема:

  • 199711L для C++98
  • 201103L для C++11
  • 201402L для C++14

Використання приблизно таке:

  std::list<int> someList ;
#if (__cplusplus >= 201103L)
  auto it = std::find(someList.begin(), someList.end(), 25);
#else
  std::vector<int>::iterator it;
  it = find (someList.begin(), someList.end(), 25);
#endif

Колись, дуже давно, цей макрос використовувався для того, щоб відрізнити компілятор C++ від чистого C; при цьому перевірка виконувалась просто на наявність. Якщо треба зберегти цю особливість, можна зробити так:

#ifndef __cplusplus
#  error C++ is required
#elif __cplusplus >= 201103L
  // do some C++0x code here
#endif

Деякі версії Microsoft Visual Studio не підтримували цей макрос (див. тут ).

Інші стандартні макроси

Для багатьох нововведень існує свій окремий макрос. Для лямбд це __cpp_lambdas (а також ще пара варіантів для найновіших версій).

  std::vector<int> c ;
#if defined( __cpp_lambdas ) 
  std::for_each(c.begin(), c.end(), [](int i){ std::cout << i << ' '; });
#endif

Перелік усіх можливих макросів можна знайти на cppreference.com, також там можна знайти дати прийняття відповідних стандартів.

Boost

Як це завжди буває, у Boost є свій власний набір макросів , що визначають підтримку стандартів. Наприклад:

#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
auto increment_lambda = [](boost::int32_t i){ accumulator += i; };
#endif

Застарілі версії gcc

Правильна реалізація __cplusplus з'явилась у gcc 4.7. Якщо треба забезпечити підтримку для зовсім старих версій компілятора, слід використовувати конструкцію __GXX_EXPERIMENTAL_CXX0X :

#if defined(__GXX_EXPERIMENTAL_CXX0X) || (__cplusplus >= 201103L)
#include <cstdint>
#else
#include <stdint.h>
#endif // defined

Хоча у такому специфічному випадку краще просто перевіряти версію компілятора за допомогою __GNUC__ та __GNUC_MINOR__.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.5K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація