template<typename T>
std::string bit_representation(T &&type) {
uint8_t data[sizeof(T)];
if constexpr (std::is_copy_constructible_v<T>) {
T tmp(type);
std::memcpy(&data, &tmp, sizeof(T));
} else if (std::is_move_constructible_v<T>) {
T tmp(std::move(type));
std::memcpy(&data, &tmp, sizeof(T));
}
auto get_byte_repr = [](uint8_t byte) -> std::string {
std::string s;
constexpr size_t byte_size = sizeof(uint8_t) * 8;
s.resize(byte_size);
for (int i = byte_size - 1; i >= 0; --i) {
s[i] = ((byte & 1) == 1) ? '1' : '0';
byte >>= 1;
}
return s;
};
std::string result;
for (int i = sizeof(T) - 1; i >= 0; --i) {
result += get_byte_repr(data[i]);
}
return result;
}
我写了一个简单的bit_representation
函数,对于简单类型都很好,但我也想为传递std::initializer_list<T>
写一个统一的模板函数。
uint8_t u8 = 0xAF;
std::cout << bit_representation(u8) << std::endl; // 10101111 ok
std::cout << bit_representation((uint8_t) 0xAF) << std::endl; // 10101111 ok
std::cout << bit_representation((short) 0xAF) << std::endl; // 0000000010101111 ok
double d = 2.56;
// 0100000000000100011110101110000101000111101011100001010001111011 = d its ok iee-754
std::cout << bit_representation(d) << std::endl;
#pragma pack(1)
struct {
bool c = true;
int a = 0x00FF00FF;
} name;
#pragma pop()
// 0000000011111111000000001111111100000001 // really ok
std::cout << bit_representation(name) << std::endl; // ok
std::cout << bit_representation(true) << std::endl; // 00000001 ok
std:cout << bit_representation({1,2,3,4}) << std::endl; /* error candidate template ignored: couldn't infer template argument 'T'
std::string bit_representation(T &&type) {*/
但是bit_representation({1,2,3,4})
不工作。.我的东西需要写SFINAE Package 器编译时检测是否类型是initializer_list<T>
.
我期望bit_representation({1,2,3,4})
-〉std::initializer_list到内存repr -〉00000000000000000000000000000001000000000000000000000000000000100000000000000000000000000000001100000000000000000000000000000100
如何推导std::initializer_list参数并为此编写特殊逻辑。
2条答案
按热度按时间66bbxpm51#
std::initializer_list
有点特殊。特别是(来自cppreference):std::initializer_list
对象在以下情况下自动构造:std::initializer_list
参数std::initializer_list
参数bit_representation({1,2,3,4})
不是这些。{1,2,3,4}
不是std::initializer_list
。只有在特定的上下文中,{1,2,3,4}
才会自动构造std::initializer_list
。在所有其他上下文中,{1,2,3,4}
没有可以推导出的类型。你可以像这样用
std::initializer_list
调用这个函数:此外,考虑到任何对象都可以被视为字节数组。不需要复制到数组。这是由于
char
、byte
和unsigned char
的严格混叠例外,如下所述:https://en.cppreference.com/w/cpp/language/reinterpret_cast。同样不清楚的是,为什么你的函数没有直接使用它的参数type
(相当容易误导的名字),而是在复制到数组之前做了另一个不必要的复制tmp
。这可能会给予你一个更好的开始(未经测试):
slhcrj9b2#
最终,这个解决方案出现了,但我不确定它是否正确解决方案
输出