【问题标题】:problem with constexpr constructor requiring constant member functionconstexpr 构造函数需要常量成员函数的问题
【发布时间】:2026-01-21 21:05:01
【问题描述】:

我的代码与需要成员函数为常量的编译器有关。我不确定如何让它工作,因为我需要在 get 函数中修改m_data,因此它不能是一个常量成员函数。

这是代码

#include <array>
#include <cstdint>
#include <cstdlib>

template <typename t, const size_t size, const size_t key>
class XorArray {
 public:
  // holds encrypted array data
  std::array<t, size> m_data;

  // compile-time create xor array
  __attribute__((always_inline)) constexpr XorArray(
      const std::array<t, size> &elements)
      : m_data{} {
    for (size_t i = 0; i < size; ++i) m_data[i] = elements[i] ^ key;
  }

  // retrive unxored data at runtime
  __attribute__((always_inline)) const t *get(){
    for (auto &element : m_data) element ^= key;

    return m_data.data();
  }
};

static constexpr std::array<uint8_t, 5> test_data = {68, 88, 66, 67, 80};

int main() {
  static constexpr auto test_data_enc =
      XorArray<uint8_t, test_data.size(), 0x5>(test_data);

      const auto test_get = test_data_enc.get();

  return 0;
}

错误信息是

error: passing 'const XorArray<unsigned char, 5, 5>' as 'this' argument discards qualifiers [-fpermissive]

const auto test_get = test_data_enc.get();

demo

【问题讨论】:

  • 那么,调用 get 两次会发生什么?
  • 为什么要修改会员?你不能只返回一个新数组/写入一个由非const 引用传递的数组吗?

标签: c++ visual-c++ stl


【解决方案1】:

您可以在本地变量中计算未异或的数据并将其返回。

  __attribute__((always_inline)) const std::array<t, size> get() const {
    auto data = m_data;
    for (auto &element : data) element ^= key;

    return data;
  }

或者存储原始元素并返回它们。

  std::array<t, size> m_data;
  std::array<t, size> m_elements;

  // compile-time create xor array
  __attribute__((always_inline)) constexpr XorArray(
      const std::array<t, size> &elements)
      : m_data{}, m_elements(elements) {
    for (size_t i = 0; i < size; ++i) m_data[i] = elements[i] ^ key;
  }

  // retrive unxored data at runtime
  __attribute__((always_inline)) const t *get() const {
    return m_elements.data();
  }

【讨论】:

  • 为什么不能修改成员?
  • 因为一个 constexpr 对象。其成员无法修改。