#include <iostream>
#include "Register.h"
int main() {
// Basic constructors
Reg8 r8{ 0xC4 };
Reg16 r16{ 0x1234 };
Reg32 r32{ 0x89ABCDEF };
Reg64 r64{ 0xABBA04200240ABBA };
// I can do this with similar types:
Reg8 r8b = r8; // okay
Reg16 r16b = r16; // okay
Reg32 r32b = r32; // okay
Reg64 r64b = r64; // okay
Reg8 r8c;
r8c = r8; // okay
Reg16 r16c;
r16c = r16; // okay
Reg32 r32c;
r32c = r32; // okay
Reg64 r64c;
r64c = r64; // okay
// Attempting with different Register Types.
// Now Fixed by doing the following:
// Reg16 r16d = r8; // Not okay - need to static_cast it.
Reg16 r16d = static_cast<Reg16>(r8); // okay
// What I would like to do:
Reg16 r16e;
r16e = r32; // not okay:
// NOTE: You can see some of my attempts of overloading
// specializing the operator=() below the class section.
return EXIT_SUCCESS;
}
注册。h
#pragma once
#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstdint>
#include <iterator>
#include <iostream>
#include <iomanip>
#include <limits>
#include <map>
#include <string>
#include <type_traits>
namespace vpc {
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
template<typename T>
struct Register;
using Reg8 = Register<u8>;
using Reg16 = Register<u16>;
using Reg32 = Register<u32>;
using Reg64 = Register<u64>;
template<typename T>
struct Register {
T value;
T previous_value;
std::bitset<sizeof(T)* CHAR_BIT> bits;
Register() : value{ 0 }, previous_value{ 0 }, bits{ 0 } {}
template<typename V, std::enable_if_t<(sizeof(V) > sizeof(T))>* = nullptr>
explicit Register(const V val, const u8 idx = 0) :
value{ static_cast<T>((val >> std::size(bits) * idx) &
std::numeric_limits<std::make_unsigned_t<T>>::max()) },
previous_value{ 0 },
bits{ value }
{
constexpr u16 sizeT = sizeof(T);
constexpr u16 sizeP = sizeof(V);
assert((idx >= 0) && (idx <= ((sizeP / sizeT) - 1)) );
}
template<typename V, std::enable_if_t<(sizeof(V) < sizeof(T))>* = nullptr>
explicit Register(const V val, const u8 idx = 0) :
value{ static_cast<T>((static_cast<T>(val) << sizeof(V)*CHAR_BIT*idx) &
std::numeric_limits<std::make_unsigned_t<T>>::max()) },
previous_value{ 0 },
bits{ value }
{
constexpr u16 sizeT = sizeof(T);
constexpr u16 sizeP = sizeof(V);
assert((idx >= 0) && (idx <= ((sizeT / sizeP) - 1)) );
}
template<typename V, std::enable_if_t<(sizeof(V) == sizeof(T))>* = nullptr>
explicit Register(const V val, const u8 idx = 0) :
value{ static_cast<T>( val ) }, previous_value{ 0 }, bits{ value }
{}
// the explicit on the copy constructor was the culprit
template<typename V>
/*explicit*/ Register(const Register<V>& reg, const u8 idx = 0) : Register(reg.value, idx) {}
Register& operator=(const Register& obj) {
this->value = obj.value;
this->previous_value = obj.previous_value;
this->bits = obj.bits;
return *this;
}
};
} // namespace vpc
这是重载的一些尝试-专用于operator=()
,这些都在我的类的声明中。
Reg8& operator=(const Reg16& rhs) {
Reg8 temp{ rhs };
this->value = temp.value;
this->previous_value = temp.previous_value;
this->bits = temp.bits;
return *this;
}
Reg8& operator=(const Reg32& rhs) {
Reg8 temp{ rhs };
this->value = temp.value;
this->previous_value = temp.previous_value;
this->bits = temp.bits;
return *this;
}
Reg8& operator=(const Reg64& rhs) {
Reg8 temp{ rhs };
this->value = temp.value;
this->previous_value = temp.previous_value;
this->bits = temp.bits;
return *this;
}
Reg16& operator=(const Reg8& rhs) {
Reg16 temp{ rhs };
this->value = temp.value;
this->previous_value = temp.previous_value;
this->bits = temp.bits;
return *this;
}
Reg16& operator=(const Reg32& rhs) {
Reg16 temp{ rhs };
this->value = temp.value;
this->previous_value = temp.previous_value;
this->bits = temp.bits;
return *this;
}
Reg16& operator=(const Reg64& rhs) {
Reg16 temp{ rhs };
this->value = temp.value;
this->previous_value = temp.previous_value;
this->bits = temp.bits;
return *this;
}
我相信应该有一种方法可以做到这一点,但是我不确定如何做到,如果我在正确处理这些重载的正确道路上,我不知道正确的语法和Visual Studio给我这个编译器错误:
1>------ Build started: Project: TestRegister, Configuration: Debug x64 ------
1>main.cpp
1>c:\...\register.h(109): error C2556: 'vpc::Reg16 &vpc::Register<vpc::u8>::operator =(const vpc::Reg8 &)': overloaded function differs only by return type from 'vpc::Register<vpc::u8> &vpc::Register<vpc::u8>::operator =(const vpc::Register<vpc::u8> &)'
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u8>::operator ='
1>c:\...\main.cpp(23): note: see reference to class template instantiation 'vpc::Register<vpc::u8>' being compiled
1>c:\...\register.h(109): error C2371: 'vpc::Register<vpc::u8>::operator =': redefinition; different basic types
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u8>::operator ='
1>c:\...\register.h(85): error C2556: 'vpc::Reg8 &vpc::Register<vpc::u16>::operator =(const vpc::Reg16 &)': overloaded function differs only by return type from 'vpc::Register<vpc::u16> &vpc::Register<vpc::u16>::operator =(const vpc::Register<vpc::u16> &)'
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u16>::operator ='
1>c:\...\register.h(110): note: see reference to class template instantiation 'vpc::Register<vpc::u16>' being compiled
1>c:\...\register.h(85): error C2371: 'vpc::Register<vpc::u16>::operator =': redefinition; different basic types
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u16>::operator ='
1>c:\...\register.h(86): error C2079: 'vpc::Register<vpc::u16>::temp' uses undefined struct 'vpc::Register<vpc::u8>'
1>c:\...\register.h(87): error C2059: syntax error: 'this'
1>c:\...\register.h(87): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(88): error C2059: syntax error: 'this'
1>c:\...\register.h(88): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(89): error C2059: syntax error: 'this'
1>c:\...\register.h(89): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(90): error C2059: syntax error: 'return'
1>c:\...\register.h(90): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(93): error C2143: syntax error: missing ';' before ''symbol''
1>c:\...\register.h(111): error C2059: syntax error: 'this'
1>c:\...\register.h(111): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(112): error C2059: syntax error: 'this'
1>c:\...\register.h(112): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(113): error C2059: syntax error: 'this'
1>c:\...\register.h(113): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(114): error C2059: syntax error: 'return'
1>c:\...\register.h(114): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(117): error C2143: syntax error: missing ';' before ''symbol''
1>c:\...\main.cpp(29): error C2679: binary '=': no operator found which takes a right-hand operand of type 'vpc::Reg8' (or there is no acceptable conversion)
1>c:\...\register.h(78): note: could be 'vpc::Register<vpc::u16> &vpc::Register<vpc::u16>::operator =(const vpc::Register<vpc::u16> &)'
1>c:\...\main.cpp(29): note: while trying to match the argument list '(vpc::Reg16, vpc::Reg8)'
1>c:\...\register.h(101): error C2556: 'vpc::Reg8 &vpc::Register<vpc::u64>::operator =(const vpc::Reg64 &)': overloaded function differs only by return type from 'vpc::Register<vpc::u64> &vpc::Register<vpc::u64>::operator =(const vpc::Register<vpc::u64> &)'
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u64>::operator ='
1>c:\...\main.cpp(141): note: see reference to class template instantiation 'vpc::Register<vpc::u64>' being compiled
1>c:\...\register.h(101): error C2371: 'vpc::Register<vpc::u64>::operator =': redefinition; different basic types
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u64>::operator ='
1>c:\...\register.h(103): error C2059: syntax error: 'this'
1>c:\...\register.h(103): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(104): error C2059: syntax error: 'this'
1>c:\...\register.h(104): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(105): error C2059: syntax error: 'this'
1>c:\...\register.h(105): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(106): error C2059: syntax error: 'return'
1>c:\...\register.h(106): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(109): error C2143: syntax error: missing ';' before ''symbol''
1>c:\...\register.h(93): error C2556: 'vpc::Reg8 &vpc::Register<vpc::u32>::operator =(const vpc::Reg32 &)': overloaded function differs only by return type from 'vpc::Register<vpc::u32> &vpc::Register<vpc::u32>::operator =(const vpc::Register<vpc::u32> &)'
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u32>::operator ='
1>c:\...\main.cpp(142): note: see reference to class template instantiation 'vpc::Register<vpc::u32>' being compiled
1>c:\...\register.h(93): error C2371: 'vpc::Register<vpc::u32>::operator =': redefinition; different basic types
1>c:\...\register.h(78): note: see declaration of 'vpc::Register<vpc::u32>::operator ='
1>c:\...\register.h(95): error C2059: syntax error: 'this'
1>c:\...\register.h(95): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(96): error C2059: syntax error: 'this'
1>c:\...\register.h(96): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(97): error C2059: syntax error: 'this'
1>c:\...\register.h(97): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(98): error C2059: syntax error: 'return'
1>c:\...\register.h(98): error C2238: unexpected token(s) preceding ';'
1>c:\...\register.h(101): error C2143: syntax error: missing ';' before ''symbol''
1>Done building project "TestRegister.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我尝试了许多其他方式,我搜索了google,在这里搜索了其他问题,但是似乎找不到与我的情况相关的任何东西,除非我忽略了一些东西。我该怎么做才能编译它?
编辑
由于explicit
上的Copy Constructor
被忽略,复制构造函数和赋值运算符都失败了。这给了我太多的Visual Studio编译器错误。删除该显式关键字即可解决所有问题。上面我的课程中的operator=()
就足够了。类部分下的重载或专业化甚至根本不需要。超过3个小时的时间试图解决这个问题...
答案 0 :(得分:2)
如果我正确理解了您的代码,则简单地将operator=()
用于不同的Register<T>
类型
template <typename U>
Register & operator= (Register<U> const & obj)
{ return *this = Register{obj}; }
但是当你写
Reg16 r16c = r8;
您是在打电话给建设者,而不是operator=()
。
在我看来,您必须删除其中的explicit
template<typename V>
explicit Register(const Register<V>& reg, const u8 idx = 0) : Register(reg.value, idx) {}
您还必须更正主operator=()
,因为obj
是引用,而不是指针;因此您必须使用点运算符,而不是箭头运算符
Register& operator=(const Register& obj) {
this->value = obj.value; // not obj->value
this->previous_value = obj.previous_value; // not obj->previous_value
this->bits = obj.bits; // not obj->bits
return *this;
};
传人:您的主要operator=()
是否等于默认的operator=()
?