为啥这个 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】:

为什么我会收到此警告

FirstTypechar 时,该分支中的代码仍然实例化,即使该分支永远不会真正执行。

我该如何解决?

将只对某些类型有意义的代码移出重载或专用特征,这样一开始就不会为不匹配的类型编译。

最简单的改变就是完全去掉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 代码会给我一个整数到指针转换警告?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 heroku 会给我这个“不兼容的类型”错误?

为啥这个 fgets 函数会给我一个分段错误?

为啥使用溢出会给我这个问题?

为啥这个表创建脚本会给我错误?

为啥在我制作折线图时,plotly express 会给我一个属性错误?

为啥这会给我一个空引用异常? [复制]