首页 > 解决方案 > 隐式转换产生“错误:获取临时地址”(GCC vs clang)

问题描述

在尝试使用强类型整数时,我遇到了来自 GCC 8.2 的奇怪错误:

错误:取临时地址

我可以想象上述错误有意义的典型场景,但就我而言,我没有遇到问题。重现错误的缩小(人为)示例如下:

#include <cstddef>

#include <type_traits>

enum class Enum : std::size_t {};

struct Pod {
  std::size_t val;

  constexpr operator Enum() const {
    return static_cast<Enum>(val);
  }
};

template<std::size_t N>
constexpr void foo() {
  using Foo = std::integral_constant<Enum, Pod{N}>;
  // [GCC] error: taking address of temporary [-fpermissive]
}

int main() {
  foo<2>();
}

为什么 GCC 8.2 在这里抱怨?Clang 6.0 很高兴(请参阅 goldbolt.org)。

请注意,来自 GCC 的第二个错误可能有助于分析问题。我也不明白:

错误:没有匹配的调用函数Pod::operator Enum(Pod*)

GCC 8.2 的完整输出为

<source>: In instantiation of 'constexpr void foo() [with long unsigned int N = 2]':

<source>:22:10:   required from here

<source>:17:50: error: taking address of temporary [-fpermissive]

   using Foo = std::integral_constant<Enum, Pod{N}>;

                                                  ^

<source>:17:50: error: no matching function for call to 'Pod::operator Enum(Pod*)'

<source>:10:13: note: candidate: 'constexpr Pod::operator Enum() const'

   constexpr operator Enum() const {

             ^~~~~~~~

<source>:10:13: note:   candidate expects 0 arguments, 1 provided

Compiler returned: 1

标签: c++compiler-errorsg++c++17clang++

解决方案


这显然是一个错误;'Pod::operator Enum(Pod*)'是胡说八道。您不能将参数传递给operator Enum.

编译器似乎认为在编译器时将 a 转换为 a 的正确操作是Foo什么。这两者都解释了“临时地址”和下一行。Enumfoo.operator Enum(&foo)


推荐阅读