c++ - 静态数组成员在上下文中是私有的
问题描述
我喜欢认为我已经掌握了面向对象编程的大部分方面,但是 C++ 再次给我带来了意想不到的结果。在 C++ 中创建静态数组类(很像 std::array)时,我添加了 + 运算符,它给了我一个非常奇怪的编译器错误。
有没有人遇到过这种情况?
#pragma once
#ifdef NDEBUG
#define __ESL_Array_AssertCorrectInitSize(array, init)
#else
#define __ESL_Array_AssertCorrectInitSize(array, init) if (init.size() != array->Size()) throw ESL::ArrayInitializationException("std::initializer_list size is different than static size");
#endif // NDEBUG
#include<cstdint>
#include<utility>
#include<stdexcept>
namespace ESL
{
class ArrayInitializationException : public std::runtime_error
{
public:
ArrayInitializationException(const std::string &msg): std::runtime_error(msg) {}
};
template <typename T, uint32_t S>
class Array
{
public:
Array(): m_data() {}
Array(const T (&arr)[S]):
m_data()
{
const T *src_itr = arr;
T *dst_itr = m_data;
for (uint32_t i = 0; i < S; ++i)
*(dst_itr++) = *(src_itr++);
}
Array(std::initializer_list<T> list):
m_data()
{
__ESL_Array_AssertCorrectInitSize(this, list)
const T *src_itr = list.begin();
T *dst_src = m_data;
for (uint32_t i = 0; i < S; ++i)
{
*(dst_src++) = *(src_itr++);
}
}
Array(const Array &a):
m_data()
{
const T *src_itr = a.m_data;
T *dst_itr = m_data;
for (uint32_t i = 0; i < S; ++i)
*(dst_itr++) = *(src_itr++);
}
Array(Array &&a):
m_data()
{
T *src_itr = a.m_data;
T *dst_itr = m_data;
for (uint32_t i = 0; i < S; ++i)
*(dst_itr++) = std::forward<T>(*(src_itr++));
}
Array &operator=(const Array &a)
{
const T *src_itr = a.m_data;
T *dst_itr = m_data;
for (uint32_t i = 0; i < S; ++i)
*(dst_itr++) = *(src_itr++);
return *this;
}
Array &operator=(Array &&a)
{
const T *src_itr = a.m_data;
T *dst_itr = m_data;
for (uint32_t i = 0; i < S; ++i)
*(dst_itr++) = std::forward<T>(*(src_itr++));
return *this;
}
constexpr uint32_t Size() const { return S; }
const T &operator[](uint32_t index) const { return m_data[index]; }
T &operator[](uint32_t index) { return m_data[index]; }
const T *begin() const { return m_data; }
T *begin() { return m_data; }
const T *end() const { return m_data + S; }
T *end() { return m_data + S; }
bool operator==(const Array &a) const
{
const T *itr1 = m_data;
const T *itr2 = a.m_data;
for (uint32_t i = 0; i < S; ++i)
{
if (*(itr1++) != *(itr2++)) return false;
}
return true;
}
bool operator!=(const Array &a) const
{
const T *itr1 = m_data;
const T *itr2 = a.m_data;
for (uint32_t i = 0; i < S; ++i)
{
if (*(itr1++) != *(itr2++)) return true;
}
return false;
}
template <uint32_t S2>
Array<T, S + S2> operator+(const Array<T, S2> &a) const
{
Array<T, S + S2> res;
const T *src_itr = m_data;
T *dst_itr = res.m_data;
for (uint32_t i = 0; i < S; ++i)
*(dst_itr++) = *(src_itr++);
src_itr = a.m_data;
for (uint32_t i = 0; i < S2; ++i)
*(dst_itr++) = *(src_itr++);
return res;
}
private:
T m_data[S];
};
}
如果您需要更多代码,我愿意发布整个文件。我很感激任何意见!谢谢!
编辑:刚刚意识到我忘记了编译器输出:
In instantiation of ‘ESL::Array<T, (S + S2)> ESL::Array<T, S>::operator+(const ESL::Array<T, S2>&) const [with unsigned int S2 = 2; T = double; unsigned int S = 3]’:
[build] /home/joshlengel/Dev/C++/ESL/Main.cpp:10:20: required from here
[build] /home/joshlengel/Dev/C++/ESL/ESL/include/collection/Array.h:135:30: error: ‘double ESL::Array<double, 5>::m_data [5]’ is private within this context
[build] 135 | T *dst_itr = res.m_data;
[build] | ~~~~^~~~~~
[build] /home/joshlengel/Dev/C++/ESL/ESL/include/collection/Array.h:149:11: note: declared private here
[build] 149 | T m_data[S];
解决方案
原因是针对类的,Array<double, 2>
而且Array<double, 3>
是完全不同的两个类。这就是为什么它说你不能访问私人成员。为此,您要么必须m_data
公开成员,要么begin()
像这样使用,
template <uint32_t S2>
Array<T, S + S2> operator+(const Array<T, S2>& a) const
{
Array<T, S + S2> res;
// You can ditch the for loops and use std::copy instead. It *can* be more efficient.
std::copy(begin(), end(), res.begin());
std::copy(a.begin(), a.end(), res.begin() + S);
return res;
}
推荐阅读
- sql-server - InterSystems 缓存数据库和 SSMS 集成服务目录
- java - 使用 Apache poi 插入具有不同列号的新表行
- excel - 如果单元格包含“拾取”,如何在另一个工作表中返回列值
- javascript - 从光滑的滑块拖动外部事件到 FullCalendar
- excel - Greater Then 使用时间公式 EXCEL 中的假数字
- css - Bulma 全高布局,中间有可滚动区域
- hyperledger-fabric - 在 Hyperledger Fabric CA 中注册和注册证书有什么区别
- cluster-computing - slurm集群管理器中如何知道一个job的每个进程的状态?
- javascript - 在 Camunda 进程中,如何使用 JavaScript 和 Spin 从 JSON 中检索布尔值?
- ios - 在 textViewDidChange 中检测粘贴 UITextView