【问题标题】:C++ compiler says "inconsistent deduction for auto return type"C++ 编译器说“自动返回类型的推导不一致”
【发布时间】:2023-01-28 19:56:39
【问题描述】:

C++ 中有一个很好的特性,您可以说该函数的返回类型为“auto”,编译器会计算出来。但是,如果我在出错时返回一个指针和 nullptr 怎么办?不知何故,编译器无法推断出正确的类型并给出错误。

在下面的简单示例中,假设 std::vector<int> 计划在未来完全被其他东西取代,以证明这里使用 auto 是合理的:

#include<vector>
std::vector<int> e;
auto test(){
  if(!e.empty())
    return &e[0];
  return nullptr;
}

在 c++17 中,我收到以上错误消息。

所以我尝试用

return reinterpret_cast&lt;decltype(&amp;e[0])&gt;(nullptr)

并得到错误invalid cast。我看到的唯一解决方案是用 3 行替换返回值:

auto out=&e[0];
out=nullptr;
return out;

我可能可以通过将 auto 替换为某种 decltype 来将其减少到 2 行,但我想其他类型的转换可以在一行中完成我想要的吗? 或者我需要为这种情况使用更新版本的 c++ 标准吗?

我还尝试了 std::make_optional 并遇到了同样的问题,nullopt_t 的类型与 std::optional 不同。 我真正喜欢的是,如果编译器无论如何都会自动将类型推断为std::optional...

【问题讨论】:

  • 提示:nullptr的类型是nullptr_t
  • deduce type to be std::optional?如果你想要 std::optional 那是完全地不同于int *

标签: c++ auto reinterpret-cast nullptr stdoptional


【解决方案1】:

对,nullptrstd::nullptr_t 类型,而不是 int* 类型。

静态投射应该没问题。

#include<vector>

std::vector<int> e;

auto test(){
  if(!e.empty())
    return &e[0];
  return static_cast<decltype(e.data())>(nullptr);
}

https://godbolt.org/z/sqfnqd69q

即使 reinterpret_cast 起作用(它不起作用),也太过分了。


我认为这是更惯用的:

#include<vector>

std::vector<int> e;

auto test(){
  if(!e.empty())
    return e.data();
  return static_cast<std::vector<int>::pointer>(nullptr);
}

我是auto的粉丝,但这是最好不要使用它的情况之一:

#include<vector>

std::vector<int> e;

auto test() -> std::vector<int>::pointer {
  if(!e.empty())
    return e.data();
  return nullptr;
}

【讨论】:

  • “更地道”天啊,两个看起来都很可怕。我认为更惯用的方法是返回 int* 而不是 auto
【解决方案2】:

只要有一个回报。

auto test() {
  return e.empty() ? nullptr : &e[0];
}

你应该用 OPs 代码解释这个问题

有两种不同类型的回报。选择哪种类型?

以及为什么这会修复它 – 463035818_is_not_a_number

因为有超长的规则条件运算符的结果是什么类型。见https://en.cppreference.com/w/cpp/language/operator_other#Conditional_operator

【讨论】:

  • 不错的解决方案,但您应该解释 OP 代码的问题以及为什么会修复它
猜你喜欢
  • 2020-03-10
  • 2016-12-13
  • 2018-08-22
  • 1970-01-01
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多