为什么这个推导的 return 类型的内联方法还没有定义?

Why this inline method with deduced return type not defined yet?

#include <string>
#include <type_traits>

class C
{
    static auto func() { return std::string("hello"); }
    static_assert(std::is_same<decltype(func()), std::string>::value, "");
};

GCC 和 Clang 都不接受这个,说 func 在定义之前使用。为什么?

将推断的 auto return 类型更改为 std::string 使其工作。

decltype 构造生成标识符或表达式的声明类型。当使用 return 类型声明 func 时,调用表达式 func() 的类型是已知的并且一切都按预期工作。

然而,当func声明为return类型占位符auto时,那么func的声明取决于它的定义,因此 func 的类型以及表达式 func() 的类型在定义函数之前是未知的。

当您在 class 定义中内联定义一个 class 成员函数时,就好像该定义紧跟在 class 定义的结尾(即,函数体可能会引用在 class 定义中 later 词法声明的名称)。这个结果和 auto 的语义是你的函数 auto func 实际上没有完全 声明 直到 class 定义结束,并且因此 func() 的类型直到那时才能知道。

除了其他答案之外,一个可能的解决方法是将检查推迟到静态函数并依靠优化器删除所有冗余代码。

在发布版本中,这应该是零成本:

#include <string>
#include <type_traits>
#include <iostream>

struct C
{
    static auto func() {
        check_same();
        return std::string("hello");
    }

private:

    static void check_same()
    {
        static_assert(std::is_same<decltype(func()), std::string>::value, "");
    }
};

int main()
{
  std::cout << C::func() << '\n';
}