constexpr конструктор и функции

У меня есть класс encrypted_string, который должен шифровать строки во время компиляции. Проблема, с которой я столкнулся, заключается в том, что я не могу вызвать функцию-член encrypt в конструкторе, но если я помещаю шифрование в сам конструктор, он работает.

template<typename I>
class encrypted_string;

template<size_t... I>
class encrypted_string<std::index_sequence<I...>>
{
 private:
  std::array<char, sizeof...(I)> buf;

  constexpr char encrypt(char c) const { return c ^ 0x41; }

 public:
  constexpr encrypted_string(const char* str)
  : buf { (str[I] ^ 0x41)... } { } // Works
  //: buf { this->encrypt(str[I])... } { } // Error
};

#define enc(str) encrypted_string<std::make_index_sequence<sizeof(str)>>(str)

int main()
{
  // Ensures compile time evaluation
  constexpr auto s = enc("Test");

  return 0;
}

Я компилирую с помощью 'g ++ encrypted_string.cpp -std = c ++ 14 -o encrypted_string', а моя версия gcc - 4.9.2.

Ошибка, которую я получаю, мало что говорит мне:

encrypted_string.cpp:17:13: note: ‘constexpr encrypted_string<std::integer_sequence<long unsigned int, _Idx ...> >::encrypted_string(const char*) [with long unsigned int ...I = {0ul, 1ul, 2ul, 3ul, 4ul}]’ is not usable as a constexpr function because:
constexpr encrypted_string(const char* str) : buf { this->encrypt(str[I])... } { }

Я что-то делаю не так, или просто невозможно вызвать функции constexpr в конструкторе constexpr? Из того, что я понял о конструкторах constexpr, это должно быть возможно.


person Freszone    schedule 27.06.2015    source источник
comment
constexpr оценивается во время компиляции, поэтому я предполагаю, что вызов методов, которые являются частью экземпляра класса, не является правильным запросом. Я не уверен в этом, но, по крайней мере, для меня это имеет смысл.   -  person skypjack    schedule 27.06.2015
comment
Прекрасно работает в gcc 5.1   -  person user657267    schedule 27.06.2015
comment
Ослабленные константные выражения C ++ 14 реализованы в gcc ›= 5, см. gcc.gnu.org /projects/cxx1y.html Согласно правилам C ++ 11, в теле конструктора может отсутствовать какой-либо код (только определения типов, статические утверждения и т. д., без потенциального кода времени выполнения).   -  person dyp    schedule 27.06.2015
comment
Сделать функцию-член static членом или нет.   -  person Tomilov Anatoliy    schedule 27.06.2015
comment
Спасибо за ответы, мне удалось скомпилировать его на gcc 4.9, изменив функцию шифрования на staticas Orient. Я обновился до gcc 5.1, и теперь он работает так, как я ожидал, без каких-либо изменений.   -  person Freszone    schedule 28.06.2015


Ответы (1)


Согласно https://gcc.gnu.org/projects/cxx1y.html, C Поддержка ++ 14 constexpr не реализована до GCC 5.

В результате GCC 4.9.2, даже с -std=c++14, поддерживает только constexprs C ++ 11, которые содержат один оператор, который производит возвращаемое значение. MSVC 2015 RC имеет такое же ограничение.

constexpr even(int n) { return (n & 1) == 0; } // valid c++11/14
constexpr even(int n) { return (n & 1) ? true : false; } // valid c++11/14
constexpr even(int n) { // valid c++14, not valid c++11
    if ((n & 1) == 0)
        return true;
    return false;
}
person kfsone    schedule 28.06.2015