提问人:vtm11 提问时间:8/28/2023 最后编辑:Jan Schultkevtm11 更新时间:8/28/2023 访问量:114
调用函数类型别名而不是函数
Calling function type alias instead of function
问:
请考虑以下代码:
#include <iostream>
using f = void(std::string);
void fcorrect(f func, std::string s) {
func(s); // calling function
};
void fmistake(f func, std::string s) {
f(s); // calling type alias instead of function
};
void myprint(std::string s) {
std::cout << s << std::endl;
};
int main() {
std::string s = "message";
fcorrect(myprint, s);
fmistake(myprint, s);
return 0;
}
函数接收函数和字符串作为参数,并按预期打印此字符串。
函数包含一个故意的错误 - 它调用类型别名而不是函数。它什么都不打印。fcorrect
myprint
fmistake
f
func
我想知道当后一个函数调用发生时,引擎盖下发生了什么?也就是说,为什么没有抛出编译时或运行时错误?
答:
3赞
Jan Schultke
8/28/2023
#1
正如评论者所说,是一个声明。关键的措辞在这里:f(s)
在涉及表达式语句和声明的语法中存在歧义:以函数式显式类型转换作为其最左边子表达式的表达式语句可能与第一个声明符以 . 在这些情况下,该声明被视为声明,但以下规定除外。
(
[ 示例 2:
class T { /* [...] */ }; // [...] T(a); // declaration // [...]
-- 结束示例 ]
类型是什么(类、函数等)并不重要,如果命名一个类型,则是一个声明。T(a)
T
该声明在这里不执行任何操作,因为它未被使用,并且等效于 或 。 在这种情况下已经是一个函数参数,所以 GCC 允许它是错误的。GCC 还允许:f(s)
f s
void s(std::string)
s
std::string s
void fmistake(f func, std::string s) {
void s(std::string);
}
// GCC also allows the following (in C++ mode)
void foo(int x) {
// GCC rejects this as re-declaring a symbol in C, but not in C++ mode.
void x(int);
}
这是一个已知的 GCC 错误 52953,于 2012 年首次报告。
评论
0赞
vtm11
9/3/2023
看来砂轮终于开始运转了
评论
f(s)
是一个声明,等效于(允许使用冗余括号)。这反过来又等价于 ,一个名为 的函数的正向声明。f s;
void s(std::string);
s
std::string
f(xyz);
s
s
f
std::string
void