соответствие класса constexpr и шаблонной функции

#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, в сообщении об ошибке содержится подробная информация об этом
семантическая проблема: дополнительный текст находится:

  1. Шаблон-кандидат проигнорирован: не удалось сопоставить ‘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() не было вычислено во время компиляции, как вы ожидали