c++ - 类型别名允许分配任意指针,尽管 int* 是预期的

标签 c++ c++11 variadic-templates template-meta-programming

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

编辑:受@Frank 启发的较短示例:

void printSquare(int x) { printf("%d\n", 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;
}

但如果没有更优雅的方法来做到这一点,我会感到惊讶。

编辑:

Directly assigning or returning the mismatching pointer does not compile

正确,但这不是你正在做的,你不是在分配指针,而是在类型转换它。语法转换极度松散。您可能已经看到以下内容:

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);

关于c++ - 类型别名允许分配任意指针,尽管 int* 是预期的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51562986/

相关文章:

c++ - 无法使用 static_cast 将枚举类转换为 int

c++ - 为什么我们需要模板模板参数的模板特化

c++ - Tic Tac Toe Minimax算法返回空板

c++ - 启动多个线程 - 实例化错误 (C++)

c++ - LPVOID 问题不接受内存地址

c++ - 在这种情况下,模板参数推导如何工作?

c++ - 验证我的编译器是否符合 c++14 的最简单的 C++ 示例?

c++ - decltype 中的可变参数模板包

c++ - 使用可变参数模板创建哈希队列

c++ - 错误 : invalid conversion from ‘int’ to ‘const char*’