在 class 定义中推导内联静态成员函数的 return 类型

Deducing the return type of an inline static member function in class definition

我正在尝试在内联函数定义之后创建 return 类型的别名以存储成员变量。我在下面简化了我的情况(我想要别名的真实类型比矢量更丑陋,真实功能比单行更复杂。)

#include <vector>
using namespace std;
struct Test {
    template <typename T>
    static auto GetVector() { return vector<T>(); }

    using VecInt = decltype(GetVector<int>());
    VecInt x;
};

但是,clang 在 using VecInt 行给我以下错误:

错误:具有推导的 return 类型的函数 'GetVector' 在定义之前无法使用。

gcc 也给我一个类似的错误。奇怪的是,这个编译,虽然它在我的情况下没有用:

#include <vector>
using namespace std;
struct Test {
    template <typename T>
    static auto GetVector() { return vector<T>(); }

    void dummy() {
        using VecInt = decltype(GetVector<int>());
        VecInt x;
    }
};

有没有办法在内联定义后添加别名?或者,我可以将 GetVector() 函数移动到结构的顶部,代码将编译。但是,我想把它放在那里。

中间类型定义有帮助吗?类似于:

#include <vector>
struct Test
{
    template <typename T>
    using MySimplerType = std::vector<T>;

    template <typename T>
    static auto GetVector() { return MySimplerType<T>(); }

    using VecInt = MySimplerType<int>;
    VecInt x;
};

有没有注意到如何从其他成员函数内部调用内联定义的成员函数,即使被调用者比调用者更远 class?之所以起作用,是因为编译器采用成员函数的内联定义,并将定义移动到 [=21= 的底部,就在 } 部分之后。所以你实际上有一个隐含的前向声明。

对于像 using 声明这样的类型别名,不是。这些声明恰好存在于 class 中的位置;他们不能引用 class.

后面的声明或定义

因为函数的 return 值不能仅通过声明推导出来,而实际定义(推导出 return 值所需的东西)存在于 class,您的 using 别名无法编译。除了直接声明函数的 return 值之外,您无能为力。或者将类型别名声明为具有所需类型,然后让函数使用该别名。

成员函数体是一个complete-class context,也就是说class在那里算是完整的了。在成员函数体内,名称查找可以找到 typedef 的任何其他成员函数或数据成员 - 无论它是在函数之前还是之后声明的。

由于GetVector()有占位符类型,需要等到class完成后才能实例化body,推导出return类型

但是别名声明是不是完整的-class上下文。您需要弄清楚 VecInt 是什么 在那一点 ,而 class 还没有完成。由于 GetVector() 需要 class 先完成,所以这是行不通的。

您需要 (a) 明确指定 GetVector() 的 return 类型,(b) 明确指定 VecInt,或 (c) 移动 GetVector() 从这个 class 中(无论是让它成为一个自由函数还是将它移动到一个基础 class):

#include <vector>

struct TestBase {
    template <typename T>
    static auto GetVector() { return std::vector<T>(); }
};

struct Test : TestBase {
    using VecInt = decltype(GetVector<int>());
    VecInt x;
};