1

I have this class encrypted_string, which should encrypt strings at compile time. The issue I'm having is that I can't call the 'encrypt' member function in the constructor, but if I place the encryption in the constructor itself it works.

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;
}

I'm compiling with 'g++ encrypted_string.cpp -std=c++14 -o encrypted_string' and my gcc version is 4.9.2.

Error I'm getting doesn't tell me much:

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])... } { }

Am I doing something wrong, or is it just not possible to call constexpr functions in constexpr constructor? From what I understood about the constexpr constructors it should be possible.

5
  • A constexpr is evaluated at compile time, so I guess invoking methods which are part of an instance of a class is not properly a valid request. I'm not sure about that, but it makes sense at least for me. Commented Jun 27, 2015 at 10:32
  • Works fine in gcc 5.1 Commented Jun 27, 2015 at 12:16
  • 1
    The C++14 relaxed constant expressions are implemented in gcc >= 5, see gcc.gnu.org/projects/cxx1y.html With the C++11 rules, may not have any code within the constructor body (only typedefs, static asserts etc., no potential run-time code). Commented Jun 27, 2015 at 12:27
  • Make member function static or not member. Commented Jun 27, 2015 at 20:52
  • Thank you for the answers, I was able to compile it on gcc 4.9 by changing the encrypt function to staticas Orient pointed out. I updated to gcc 5.1 and now it works as I expected it to work without any modifications. Commented Jun 27, 2015 at 21:16

1 Answer 1

2

According to https://gcc.gnu.org/projects/cxx1y.html, C++14 constexpr support is not implemented until GCC 5.

As a result, GCC 4.9.2, even with -std=c++14, only supports C++11 constexprs which comprise a single statement that produces a return value. MSVC 2015 RC has the same limitation.

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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.