含默认参数的函数指针及GCC版本编译差异技术问询
解答你的两个C++问题
1. 使用函数指针时是否必须显式指定所有参数,即使原函数有默认参数?
是的,必须显式传够函数指针类型要求的所有参数。原因在于:
- 函数的默认参数是编译器在调用点的语法糖——只有直接调用函数名时,编译器才会根据函数声明自动补全默认参数。
- 函数指针的类型是严格匹配的,比如你定义的
Ptr类型是int (*)(std::string, size_t),它只记录了函数的签名(参数类型、返回值类型),并不会携带原函数的默认参数信息。 - 当你通过函数指针调用时,编译器只会按照指针的签名检查参数数量,完全不知道原函数有默认参数存在。所以必须传入两个参数,比如
p("10", 0)才能通过编译,这是符合C++标准的行为。
2. GCC 5.3.1针对模板包装器的实现是否存在错误?
没错,GCC 5.3.1的行为是不符合C++标准的,属于编译器bug。
- 在你的模板包装器代码中,
(*T::value)(s)本质是调用一个类型为int (*)(std::string, size_t)的函数指针,按照标准必须传入两个参数。 - GCC 5.3.1错误地将原函数
foo的默认参数信息“关联”到了函数指针上,允许你省略第二个参数,这是不符合标准的行为。 - 后续的GCC 6.3.1和7.2.1修复了这个bug,严格按照标准要求检查函数指针调用的参数数量,所以编译报错才是正确的、符合标准的结果。
内容的提问来源于stack exchange,提问作者Artur Pyszczuk
相关产品推荐
相关产品推荐

