我們有一些代碼,看起來像這樣:強制使用固定大小類型的內部API的調用者?
class Serializer
{
public:
template<class Type> void Write(const Type& value)
{
internal_write((byte*)value, sizeof(Type));
}
// some overloads of Write that take care of some tricky type we have defined
private:
// implementation of internal_write
};
正如人們所猜測這將數據寫入到磁盤。我們有類似的讀取函數,或多或少將某些字節轉換爲類型。雖然不像它可能的那樣健壯,但它有效,因爲我們在讀取的同一個平臺上編寫 - 這意味着我們寫入的字節與我們需要讀取的字節相匹配。
我們現在正在移動以支持多種平臺。我們在幾個地方的代碼,如:
unsigned long trust_me_this_will_be_fine = get_unsigned_long();
a_serializer.Write(trust_me_this_will_be_fine);
,在當前世界工作正常,但如果我們假設我們要支持的平臺之一具有unsigned long
爲32位,並在另一個他們是64位,我們被洗腦了。
我想將Serializer::Write
更改爲僅顯式大小的類型作爲參數。我想這個問題:
class Serializer
{
public:
void Write(uint32_t value) { ... }
void Write(uint64_t value) { ... }
};
但我不覺得這確實解決了這個問題,因爲32位系統上,一個unsigned long
會自動轉換成uint32_t
但在64位系統上它會自動轉換爲uint64_t
。
我真的想在這裏是讓Write(uint32_t)
只接受型uint32_t
--meaning,這將需要顯式的轉換參數。我不認爲有一個直接的方法可以做到這一點 - 如果我錯了,請告訴我。
簡而言之,我可以想出兩種方法來解決這個問題。
- 申報(但不定義)爲每個類型可以自動轉換成我們支持一種類型的
Serializer::Write
專用版本。 - 不要直接拿
uint32_t
,而是一個擁有uint32_t
的類,並且只有uint32_t
的顯式構造函數。
選項2會是這個樣子:
class only_uint32
{
public:
uint32_t _value;
explicit only_uint32(uint_32 value) : _value(value) { }
};
class Serializer
{
public:
void Write(only_uint32 value) { ... }
};
然後調用代碼如下所示:
unsigned long might_just_work = get_unsigned_long();
a_serializer.Write(static_cast<uint32_t>(might_just_work)); // should work, and be explicitly sized.
a_serializer.Write(might_just_work); // won't compile
我認爲很多人都解決了這類問題。有沒有這樣做的首選方法,我沒有想到?我的想法之一是可怕的,偉大的,可行的嗎?
P.S .:是的,我知道這是一個超長的帖子。不過,這是一個相當複雜和詳細的問題。
更新:
感謝您的想法和幫助。我認爲我們有解決方案,像這樣去:
class Serializer
{
public:
template<class Type> void Write32(const Type& value)
{
static_assert(sizeof(Type) == 4, "Write32 must be called on a 32-bit value.");
internal_write(reinterpret_cast<byte*>(value), 4);
}
// overloads like Write64 and various tricky types as before.
private:
// implementation of internal_write
};
這是一個相當低的成本(以工程時間方面)的解決方案,成功在推你實際上節省了給調用者的知識並強制呼叫者知道他們在呼叫什麼。
如果您有一個類型具有'uint32_t'的顯式構造函數,因爲您可以將其他可轉換爲'uint32_t'的其他元素傳遞給構造函數並且將其轉換爲'uint32_t' – 2012-02-02 05:57:58
感嘆。但當然你是對的。 – SirPentor 2012-02-02 06:17:33