我今天遇到了一个有趣的问题,涉及从非匹配类型的函数指针分配给指针。
编辑:受@Frank启发的较短示例:
void printSquare(int x) { printf("%dn", x * x); }
int* foo() {
using res_t = int*;
return res_t(printSquare);
}
我希望代码不会编译,因为函数的返回类型应该是int*
的,这绝不是从类型系统边界内的函数引用或指针创建的(据我所知)。当直接返回或用int *
替换res_t
时,编译器会拒绝该程序,但中间有using
-声明,它会编译并运行(当然指向的位置不包含 int,而是一个函数)。
原始代码和问题保留在下面的单独答案中。
您不是在构造指针,而是在强制转换指针,这在 C 样式的指针转换规则下是合法的。
举个例子,以下内容等效于您正在做的事情,并且可以很好地编译(不幸的是,但出于兼容性原因,这是必需的):
float some_val = 0.0f;
int* foo() {
using res_t = int*;
return res_t(&some_val);
}
在我的头顶上,你可以像这样解决这个问题:
if(pos != end(container)) {
return pos->second;
}
else {
C val(std::forward<First>(first), std::forward<Args>(args)...);
return val;
}
但是,如果没有更优雅的方法可以做到这一点,我会感到惊讶。
编辑:
直接赋值或返回不匹配指针不会编译
正确,但这不是你正在做的事情,你不是在分配指针,而是在投射它。语法强制转换非常松散。您可能已经看到以下内容:
int * a;
float * b = (float*)a;
现在考虑一下转换在数值类型之间的工作方式:
int a = 0;
short b = (int)a;
short c = int(a);
">b"和"c"语句是等效的。第三个语句不是构造,它仍然是一个强制转换,相同的语法规则适用于指针(为了保持一致性)。
但是:c
使用的语法(函数式强制转换)不能直接访问,因为以下内容没有语法意义:
float* d = float*(&a);
但是在使用类型别名时它仍然可以工作:
using float_ptr = float*;
float* d = float_ptr(&a);