我正在嘗試制作一個函式模板,讓我處理 POD 資料型別和字串的原始位元組。
我想出了這個有點天真的方法(我沒有經常使用模板,我能夠撰寫它們只在非常簡單的情況下使用它們):
#include <cstdio>
template<typename T>
void PrintBytes(T object)
{
unsigned char* p = reinterpret_cast<unsigned char*>(&object);
for (int i = 0; i < sizeof object; i )
{
printf("x ", *p );
}
printf("\n");
}
int main()
{
int a = 10;
PrintBytes(a); // works as expected
short b = 12;
PrintBytes(b); // works as expected
const char* foo = "ABC";
PrintBytes(foo); // works as expected, but doesn't do what I want
const char bar[] = "ABC";
PrintBytes(bar); // works as expected, but doesn't do what I want
}
輸出
0a 00 00 00
0c 00
a4 ac 5b 8c f6 7f 00 00
a4 fb 7f 07 b7 00 00 00
最后兩種情況的期望輸出
41 42 43
41 42 43
顯然,前兩種情況有效,后兩種情況無效,因為fooandbar已經是指標,而unsigned char* p = reinterpret_cast<unsigned char*>(&object)should beunsigned char* p = object和sizeof objectshould be strlen(object)。
如何使用 C 模板完成此操作?我可以使用 c 17。
uj5u.com熱心網友回復:
可以使用C 17if constexpr根據 的型別執行相應的地址和大小方法T,如下所示:
#include <cstdio>
#include <cstring>
#include <utility>
#include <type_traits>
template<typename T>
void PrintBytes(T object)
{
auto [p, size] = [&] {
if constexpr (std::is_same_v<T, const char*>)
return std::pair{object, strlen(object)};
else
return std::pair{reinterpret_cast<unsigned char*>(&object), sizeof(object)};
}();
for (int i = 0; i < size; i )
{
printf("x ", *p );
}
printf("\n");
}
演示。
uj5u.com熱心網友回復:
讓我們擴展編譯器在使用字符陣列或指標呼叫 PrintBytes 時的作用。
你打電話:
const char* foo = "ABC";
PrintBytes(foo); // works as expected, but doesn't do what I want
然后編譯器必須為給定的引數實體化函式 PrintBytes,一個 const char*,它給出:
void PrintBytes(const char* object)
{
unsigned char* p = reinterpret_cast<unsigned char*>(&object);
for (int i = 0; i < sizeof (object); i ) // sizeof(const char*) is 8, for a 64 biut app.
{
printf("x ", *p ); // this will print the value of object, NOT what it points to.
}
printf("\n");
}
要強制 PrintBytes(const char*) 列印字串的 cntexnts,而不是其地址,您應該為字串創建一個特定于型別的覆寫,如下所示:
void PrintBytes(const char* sz)
{
// you may want to check for sz itself being NULL before proceding
if (sz)
{
do
{
printf("x ", *sz); // this will print the value of object, NOT its address
} while (*sz != 0);
}
printf("\n");
}
uj5u.com熱心網友回復:
我終于想出了這個:
#include <cstdio>
#include <cstring>
void PrintBytes(const unsigned char *p, size_t len)
{
for (int i = 0; i < len; i )
{
printf("x ", *p );
}
printf("\n");
}
template<typename T>
void PrintBytes(T object)
{
const unsigned char* p = reinterpret_cast<const unsigned char*>(&object);
PrintBytes(p, sizeof object);
}
template<>
void PrintBytes(const char *object)
{
auto len = strlen(object);
const unsigned char* p = reinterpret_cast<const unsigned char*>(object);
PrintBytes(p, len);
}
template<>
void PrintBytes(char* object)
{
auto len = strlen(object);
const char* p = reinterpret_cast<const char*>(object);
PrintBytes(p);
}
int main()
{
int a = 10;
PrintBytes(a); // works as expected
short b = 12;
PrintBytes(b); // works as expected
float f = 1.2f;
PrintBytes(f); // works as expected
const char* foo = "ABC"; // works as expected
PrintBytes(foo);
char bar[] = "ABC"; // works as expected
PrintBytes(bar);
}
uj5u.com熱心網友回復:
#include <cstdio>
template<typename T>
void PrintBytes(T& object)
{
const unsigned char* p = reinterpret_cast<const unsigned char*>(&object);
for (int i = 0; i < sizeof object; i )
{
printf("x ", p[i]);
}
printf("\n");
}
int main()
{
int a = 10;
PrintBytes(a); // works as expected
short b = 12;
PrintBytes(b); // works as expected
const char* foo = "ABC";
PrintBytes(foo);
// Print the content of the pointer foo, which is an address;
// I think this work as expected as the "object" is just a pointer;
// if you want to print the content of the data it points to instead,
// you need another implementation logic of this "PrintBytes",
// which would be an function overload, like some other answers show.
const char bar[] = "ABC";
PrintBytes(bar); // print "41 42 43 00"
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/361048.html
