Есть два «функция-тест» макросы, которые вы можете поместить использовать здесь:
__has_feature
и __has_extension
Эти функции, как макросы с одним аргументом идентификатор, имя функции. __has_feature
оценивает 1, если эта функция поддерживается Clang и стандартизирована в текущем стандарте языка или 0, если нет, тогда как __has_extension
оценивает 1, если эта функция поддерживается Clang на текущем языке (либо в качестве расширения языка, либо на стандартном языке функция) или 0, если нет.
Эти макросы и идентификаторы описаны здесь:
http://clang.llvm.org/docs/LanguageExtensions.html
В вашем конкретном примере, следующий HelloWorld является наиболее информативным:
#if __has_extension(cxx_generalized_initializers)
#warning __has_extension(cxx_generalized_initializers) is true
#else
#warning __has_extension(cxx_generalized_initializers) is false
#endif
#if __has_feature(cxx_generalized_initializers)
#warning __has_feature(cxx_generalized_initializers) is true
#else
#warning __has_feature(cxx_generalized_initializers) is false
#endif
#if __has_extension(cxx_range_for)
#warning __has_extension(cxx_range_for) is true
#else
#warning __has_extension(cxx_range_for) is false
#endif
#if __has_feature(cxx_range_for)
#warning __has_feature(cxx_range_for) is true
#else
#warning __has_feature(cxx_range_for) is false
#endif
int main()
{
}
Для меня, с -std = с ++ 03 его выходы:
test.cpp:4:2: warning: __has_extension(cxx_generalized_initializers) is false [-W#warnings]
#warning __has_extension(cxx_generalized_initializers) is false
^
test.cpp:10:2: warning: __has_feature(cxx_generalized_initializers) is false [-W#warnings]
#warning __has_feature(cxx_generalized_initializers) is false
^
test.cpp:14:2: warning: __has_extension(cxx_range_for) is true [-W#warnings]
#warning __has_extension(cxx_range_for) is true
^
test.cpp:22:2: warning: __has_feature(cxx_range_for) is false [-W#warnings]
#warning __has_feature(cxx_range_for) is false
^
4 warnings generated.
Принимая во внимание, что с -std = C++ 11 выходные изменения:
test.cpp:2:2: warning: __has_extension(cxx_generalized_initializers) is true [-W#warnings]
#warning __has_extension(cxx_generalized_initializers) is true
^
test.cpp:8:2: warning: __has_feature(cxx_generalized_initializers) is true [-W#warnings]
#warning __has_feature(cxx_generalized_initializers) is true
^
test.cpp:14:2: warning: __has_extension(cxx_range_for) is true [-W#warnings]
#warning __has_extension(cxx_range_for) is true
^
test.cpp:20:2: warning: __has_feature(cxx_range_for) is true [-W#warnings]
#warning __has_feature(cxx_range_for) is true
^
4 warnings generated.
Для Вашего случая использования, вы можете зашнуровать ваш код с __has_extension(cxx_generalized_initializers)
и использовать новую функцию, когда правда, еще работают вокруг него, когда ложное. Затем ваш код будет автоматически адаптироваться при обновлении вашего clang или при изменении режима использования языка.
Что касается того, какая функция языка поддерживается, а какая нет, документация может помочь, но я считаю, что написать тест, такой как выше, является самым быстрым и точным способом оценить мою текущую версию clang.
Ницца! Я написал небольшую программу, чтобы перечислить все функции. С точки зрения Clang 4.2 кажется, что * удаленные функции, встроенные пространства имен, аргументы шаблонов локального типа, переопределяющие ключевые слова управления, ссылочные квалифицированные функции, диапазон для ссылок * и * rvalue *. – nneonneo
Что странно в том, что '__has_extension (cxx_auto_type)' является ложным, но (как вы можете видеть в моем примере) 'auto & i' компилируется просто отлично. – nneonneo
@nneonneo: Кажется, что в Clang 3.3 (devel.версия), все тесты компилируются в 'true', за исключением 'cxx_inheriting_constructors'. И согласно [их таблице] (http://clang.llvm.org/cxx_status.html), кажется, что 'thread_local' также будет отсутствовать в следующей версии. Но он приближается. Я бы предположил, что они не делают значение '__has_extension' равно true, пока поддержка не станет окончательной и стабильной, поэтому' cxx_auto_type' может оценивать значение false, пока код работает. –