类型别名允许分配任意指针,尽管 int* 是必需的

Type alias allows assignment of arbitrary pointer although int* is expected

本文关键字:int 尽管 指针 任意 许分配 别名 分配 类型      更新时间:2023-10-16

我今天遇到了一个有趣的问题,涉及从非匹配类型的函数指针分配给指针。

编辑:受@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);