Я только что попытался скомпилировать довольно большой объем кода, используя clang 3.3 с заголовочными файлами стандартной библиотеки GCC 4.7.3 в Ubuntu 13.04. Все прошло хорошо, кроме одного вопроса. Этот код уже компилируется со стандартным пакетом Ubuntu clang 3.2 на этом компьютере, поэтому я предполагаю, что это некоторое изменение в компиляторе clang 3.3. Проблема связана с const и constexpr с использованием сложного заголовка. В частности, сложный тип имеет следующий блок кода
#ifdef __GXX_EXPERIMENTAL_CXX0X__
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
constexpr double
real() { return __real__ _M_value; }
constexpr double
imag() { return __imag__ _M_value; }
#else
double&
real() { return __real__ _M_value; }
const double&
real() const { return __real__ _M_value; }
double&
imag() { return __imag__ _M_value; }
const double&
imag() const { return __imag__ _M_value; }
#endif
В моей компиляции я ввожу первый блок кода, и поэтому компилятор видит
constexpr double real() { return __real__ _M_value; }
Это приводит к тому, что clang выдает ошибку, что реальная функция-член не соответствует следующему
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/complex:1212:7:
note: candidate function not viable: 'this' argument has type 'const complex<double>',
but method is not marked const
real() { return __real__ _M_value; }
Я прочитал следующий пост Разница между `constexpr` и` const` и несколько других подобных документов, но до сих пор не совсем ясно, является ли это проблемой заголовка GCC или проблемой компилятора clang. Мне кажется, что функция-член, помеченная constexpr, должна рассматриваться компилятором как const, и в этом случае clang неверен.
Согласно страница состояния для лязга, N3652 Расслабляющие требования к функциям constexpr частично реализован. Эта статья сделала большие изменения. Следующий отрывок был удален.
Спецификатор constexpr для нестатической функции-члена, которая не является
конструктор объявляет эту функцию-член const (9.3.1).
Это изменение означает, что ваша функция не может быть вызвана const
объектов больше. Также см Исправление функций-членов constexpr без const это предложение исправить те области библиотеки.
Других решений пока нет …