#c #templates #c 11 #constexpr
#c #шаблоны #c 11 #constexpr
Вопрос:
Я пробую constexpr, чтобы получить представление о функциональности, и я вижу, что это может немного упростить метапрограммирование шаблона (если я правильно его понимаю).
У меня есть этот фиктивный пример, где класс имеет поле const number, а ctor, помеченный как constexpr, должен вести себя как константа времени компиляции. Что он и делает, но каким-то образом не удается с сопоставлением функции шаблона:
#include <iostream>
class ConstNum
{
public:
constexpr ConstNum(int num) : _num(num)
{
}
constexpr int number() const
{
return _num;
}
private:
const int _num;
};
template<class T, size_t N>
constexpr int num_elements(const T (amp;arr) [N])
{
return N;
}
int main()
{
ConstNum c1(3);
char arr[c1.number()];
// fails to compile here with error message:
// No matching function for call to num_elements
//
std::cout << num_elements(arr) << std::endl;
return 0;
}
Я работаю на XCode, в сообщении об ошибке содержится подробная информация об этом
семантическая проблема: дополнительный текст находится:
- Шаблон-кандидат проигнорирован: не удалось сопоставить ‘const T[N]’ с ‘char [c1.number()]
Если я заменю c1.number () на 3, это отлично скомпилируется. Или, если я полностью удалю вызов std::cout, это нормально компилируется.
Есть идеи, чего мне здесь не хватает. Спасибо
Саранский
Ответ №1:
Даже если функция помечена как, constexpr
она может выполняться во время выполнения. Если вы хотите выполнить оценку во время компиляции, вам следует добавить constexpr
спецификатор к c1
объекту, иначе он будет создан во время выполнения:
constexpr ConstNum c1(3);
Вывод:
> ./main
3
Совет: Clang с включенными предупреждениями выдает следующий результат для вашего кода:
main.cpp:29:13: warning: variable length arrays are a C99 feature [-Wvla-extension]
char arr[c1.number()];
Это означает, что c1.number()
не было вычислено во время компиляции, как вы ожидали