我已经按此顺序提出了一系列与相同源代码相关的问题:
我还在 Code Review 上提出了一系列相关的问题。
这应该可以让您大致了解我的原始代码设计,并提供参考和背景信息。从那时起,我开始查看我的工作代码,并希望进一步简化它。
然后我决定删除模板特化,让我的寄存器类默认为 64 位宽而不是 8 位,同时专门化高阶大小的寄存器。
我试图将人们可以通过以下任何一种方式访问数据的想法结合起来:
- 完整值: - 整个 64 位 qword
- 半值: - 2 个单独的 32 位双字
- 四分之一值 - 4 个单独的 16 位字
- 第八个值 - 8 个单独的 8 位字节
并且通过实用程序的使用,std::bitset
可以轻松访问完整 64 位寄存器中的任何位。通过使用联合,我应该能够正确映射内存,以便可以将寄存器表示为并由以下任何组合访问:
std::bitset<64> qword
std::bitset<32> dword[2]
std::bitset<16> word[4]
std::bitset<8> byte[8]
使用联合的概念是在内存中有一个空间,代表任何给定寄存器的 64 位。现在我试图让我的 Register 类可以轻松复制。
因此,我将上面链接中的原始代码修改为更简单的版本:
寄存器.h
#include <algorithm>
#include <bitset>
#include <string>
#include <vector>
namespace vpc {
typedef std::int8_t i8;
typedef std::int16_t i16;
typedef std::int32_t i32;
typedef std::int64_t i64;
const std::uint16_t BYTE = 0x08;
const std::uint16_t WORD = 0x10;
const std::uint16_t DWORD = 0x20;
const std::uint16_t QWORD = 0x40;
typedef std::bitset<BYTE> Byte;
typedef std::bitset<WORD> Word;
typedef std::bitset<DWORD> DWord;
typedef std::bitset<QWORD> QWord;
union Bits {
QWord value;
DWord dword[2];
Word word[4];
Byte byte[8];
};
struct Register {
Bits bits;
Register() = default;
};
} // namespace vpc
然后我想测试以确保到目前为止的所有内容都可以轻松复制。所以我运行这个短程序。
主文件
#include <iostream>
#include <type_traits>
#include "Register.h"
int main() {
using namespace vpc;
std::cout << std::boolalpha;
std::cout << "std::bitset<64> is trivially copyable "
<< std::is_trivially_copyable<std::bitset<64>>::value << '\n'
<< "QWord is trivially copyable "
<< std::is_trivially_copyable<QWord>::value << '\n'
<< "DWord is trivially copyable "
<< std::is_trivially_copyable<DWord>::value << '\n'
<< "Word is trivially copyable "
<< std::is_trivially_copyable<Word>::value << '\n'
<< "Byte is trivially copyable "
<< std::is_trivially_copyable<Byte>::value << '\n'
<< "Bits is trivially copyable "
<< std::is_trivially_copyable<Bits>::value << '\n'
<< "Register is trivially copyable "
<< std::is_trivially_copyable<Register>::value << '\n';
return EXIT_SUCCESS;
}
我得到这个输出:
std::bitset<64> is trivially copyable true
QWord is trivially copyable true
DWord is trivially copyable true
Word is trivially copyable true
Byte is trivially copyable true
Bits is trivially copyable true
My Register is trivially copyable true
现在,当查看 union Bits 时,它声明它是可简单复制的。因此,不要将结构中的 Bits 类型的变量声明为其数据成员;我相信我们应该能够在我们的结构中拥有一个匿名联合,这样我们就可以直接访问我们的 qword、dwords、单词和字节。所以现在这个类看起来像这样:
struct Register {
union {
QWord value;
DWord dword[2];
Word word[4];
Byte byte[8];
};
Register() = default;
};
然后我在我们的 main.cpp 中运行这行代码
// code...
std::cout << std::boolalpha;
std::cout << "Register is trivially copyable "
<< std::is_trivially_copyable<Register>::value << '\n';
// code...
我得到这个输出:
Register is trivially copyable true
好的,到目前为止一切都很好。
现在我正在处理对 Register 对象进行操作的函数。它将反转从先前提出的问题中看到的位顺序。除了在这种情况下,我没有使用模板。Register.h
所以在这里我在我的课后声明函数原型:
Register reverseBitOrder( Register& reg, bool copy = false );
然后我创建了一个Register.cpp
文件来实现这个功能。
注册.cpp
#include "Register.h"
namespace vpc {
Register reverseBitOrder(Register& reg, bool copy) {
auto str = reg.value.to_string();
std::reverse(str.begin(), str.end());
if (copy) { // return a copy
Register cpy;
cpy.value = QWord(str);
return cpy;
} else {
reg.bits.value = QWord(str);
return { 0 };
}
}
} // namespace vpc
所以现在我已经编写了函数,我清理了我的解决方案,现在我尝试编译“Register.h”。然而; 我收到此编译器错误 frpm Visual Studio 2017 ,语言设置设置为最新的草案标准或标志(/std:c++latest)
。
--- Build started: Project: Corgi64, Configuration: Debug Win32 ------
1>Register.cpp
1>c:\***\register.cpp(10): error C2280: 'vpc::Register::Register(void)': attempting to reference a deleted function
1>c:\***\register.h(40): note: see declaration of 'vpc::Register::Register'
1>c:\***\register.h(40): note: 'vpc::Register::Register(void)': function was implicitly deleted because 'vpc::Register' has a variant data member 'vpc::Register::value' with a non-trivial default constructor
1>c:\***\register.h(34): note: see declaration of 'vpc::Register::value'
1>Done building project "Corgi64.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
因此,当我单击错误 C2280 时,它会将我引导至我的寄存器变量的声明cpy
。当我将鼠标光标移到变量上方时,cpy
它会给我以下消息:
vpc::注册cpy
“vpc::Register”的默认构造函数不能被引用——它是一个被删除的函数
所以我的问题变成了:如果之前的所有内容都可以轻松复制,为什么要删除默认构造函数?因为我现在在一个函数中使用它,突然之间,它表明我的结构有一个不变的成员,它没有一个可简单复制的构造函数,并且它指向Register::value
了罪魁祸首。是什么原因造成的,如何以及为什么?我能做些什么来修复或解决这个问题?