我正在尝试了解更多类类型转换。我正在阅读 C++ 入门 5ed。所以我尝试了这段代码:
int add(int x, int y) { return x + y;}
struct Foo
{
//operator(int(*)(int, int))(){return add;} // error
using pfn = int(*)(int, int);
operator pfn(){return add;} // OK
double value = 5.45;
};
int main()
{
cout << (int(*)(int, int))Foo()(5, 7) << endl; // why 1
cout << ((int(*)(int, int))Foo())(5, 7) << endl; // Ok 12
std::cout << "\nDone!\n";
}
那么为什么我不能使用类型
int(*)(int, int)
直接为我的类定义转换,但可以使用类型别名?为什么我在第一个语句中得到错误的值
1
,而在第二个语句中使用括号得到正确的值?我从第一条语句中收到警告:
描述资源路径位置类型从不同大小的整数转换为指针[-Wint-to-pointer-cast] main.cpp/MyCppProj line 31 C/C++问题
最佳答案
- So why I cannot directly define conversion for my class using the type
int(*)(int, int)
but I can with a type alias?
grammar对于转换函数的“operator
TYPE”名称,其限制比更通用的声明符或type-id要严格得多。它根本不允许括号,只允许类型说明符(如类型别名、 unsigned int
、类名等)、 *
的组合。 , &
, &&
, const
和volatile
代币,以及[[
属性 ]]
。我不能确切地说出原因,但像这样复杂的声明很难编写、读取和解析。如果允许更多,在某些情况下可能会存在潜在的歧义,或者可能他们只是不想要求编译器必须弄清楚这一点。
此外,如果允许的话,表格可能会是 operator int (*())(int, int);
而不是operator (int(*)(int, int))()
?或者也许这也没有意义。看?棘手。
- Why I get value
1
in the first statement which is erroneous and get it correct in the second statement using parenthesis?
函数调用语法更高precedence比C型 Actor 阵容。所以
(int(*)(int, int))Foo()(5, 7) // (1)
(int(*)(int, int)) (Foo()(5, 7)) // (2), same as (1)
((int(*)(int, int))Foo()) (5, 7) // (3), not the same
表达式 (1) 或 (2) 通过首先创建临时 Foo
进行计算。接下来是函数调用语法和 Foo
没有定义operator()
,但 C++ 还会检查它是否隐式转换为函数的指针或引用,并且确实如此,因此 (5, 7)
执行隐式转换并调用指向 add
的结果指针,给出 12。这被转换为函数指针类型,该类型具有实现定义的结果。没有operator<<
为函数指针声明,但有一个为 bool
,并且函数指针可以隐式转换为 bool
。据推测,奇怪的强制转换的结果不是空指针值,因此最终结果是 true
,您会看到值 1
。 (如果您之前已完成 std::cout << std::boolalpha
,您应该会看到 true
或相应的翻译。)
除了对运算符优先级的误解之外,其中之一是 C 风格强制转换的危险,它可以做很多不同的事情,其中一些通常不是有意的。使用static_cast<int(*)(int,int)>(Foo())(5,7)
相反,一切都很好。或者如果我们不小心输入了 static_cast<int(*)(int,int)>(Foo()(5,7))
相反,编译器会给出有关从 int
进行转换的错误。至int(*)(int,int)
,因为仅 reinterpret_cast
或者 C 风格的强制转换可以做到这一点。
- I get the warning from first statement:
Description Resource Path Location Type cast to pointer from integer of different size [-Wint-to-pointer-cast] main.cpp /MyCppProj line 31 C/C++ Problem
尽管 C 风格的转换强制从 int
进行转换为了使函数指针有效,编译器警告 int
没有足够的字节来表示函数指针。假设 int
之前的值来自将函数指针转换为某种数字类型,这意味着要转换回来,但是每当它从足够大的类型转换为int
时, ,指针值丢失。
关于c++ - 如何定义类类型到函数指针的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61589487/