为啥这个 type_traits 代码会给我一个整数到指针转换警告?
Posted
技术标签:
【中文标题】为啥这个 type_traits 代码会给我一个整数到指针转换警告?【英文标题】:Why is this type_traits code giving me an integer-to-pointer cast warning?为什么这个 type_traits 代码会给我一个整数到指针转换警告? 【发布时间】:2016-10-03 09:32:11 【问题描述】:没有过多的细节,我创建了一个可变参数模板函数,它根据模板参数的类型执行不同的操作。我将实现简化为一个非常简单的控制台打印示例:
#include <cstdint>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <type_traits>
void print(const char *chars)
printf("%s", chars);
template<typename FirstType, typename ... OtherTypes>
inline void print(FirstType first, OtherTypes... others);
template<typename ... OtherTypes>
inline void print(const char *chars, OtherTypes... others)
print(chars);
print(" ");
if (sizeof...(others) == 0)
print("\r\n");
else
print(others...);
template<typename FirstType, typename ... OtherTypes>
inline void print(FirstType first, OtherTypes... others)
char buffer[10];
const char *format = nullptr;
if (std::is_same<int, FirstType>::value)
format = "%d";
else if (std::is_same<char, FirstType>::value)
format = "%c";
else if (std::is_pointer<FirstType>::value && (std::is_same<char*, FirstType>::value || std::is_same<const char*, FirstType>::value))
print((const char *) first, others...);
return;
if (format != nullptr)
snprintf(buffer, 10, format, first);
print((const char *) buffer, others...);
int main()
print("this is an example:", 'X');
return 0;
在上面的代码中,我使用const char*
和char
调用可变参数函数。它工作正常,但问题是编译器给了我一个警告:
[Timur@Timur-Zenbook tm]$ g++ tm.cpp -Wall -Wextra -o tm
tm.cpp: In instantiation of ‘void print(FirstType, OtherTypes ...) [with FirstType = char; OtherTypes = ]’:
tm.cpp:24:14: required from ‘void print(const char*, OtherTypes ...) [with OtherTypes = char]’
tm.cpp:52:37: required from here
tm.cpp:40:15: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
print((const char *) first, others...);
^~~~~~~~~~~~~~~~~~~~
警告来自char
参数,好像该函数错误地将char
的类型确定为与const char*
相同,因此触发了const char*
的代码路径。
为什么会收到此警告,我该如何解决? 提前感谢您的回答!
【问题讨论】:
【参考方案1】:为什么我会收到此警告
当FirstType
为char
时,该分支中的代码仍然实例化,即使该分支永远不会真正执行。
我该如何解决?
将只对某些类型有意义的代码移出重载或专用特征,这样一开始就不会为不匹配的类型编译。
最简单的改变就是完全去掉else if(std::is_pointer...
分支,加上这个重载,效果是一样的:
template<typename ... OtherTypes>
inline void print(char *chars, OtherTypes... others)
print((const char *)chars, others...);
【讨论】:
在这种特定情况下,它将被分配一个值,因为格式为“%c”。不过,这肯定是一个等待发生的错误。并且最好断言 format != nullptr. 我不确定您是否遇到了和我一样的问题 - 当然,此示例代码中还有其他质量问题。if constexpr
会让这更容易
同意(这也将用静态分支替换剩余的重载)
太棒了,谢谢!所以基本上你是说添加重载比这样使用type_traits
更好?以上是关于为啥这个 type_traits 代码会给我一个整数到指针转换警告?的主要内容,如果未能解决你的问题,请参考以下文章