![](/img/trans.png)
[英]correct syntax for deducing return value of static member function of dependent type
[英]Deducing the return type of an inline static member function in class definition
我试图在内联函数定义之后创建一个返回类型的别名来存储成员变量。 我在下面简化了我的情况(我想要别名的真实类型比矢量更难以输入,而真正的函数比单行更复杂。)
#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
行时给出了以下错误:
错误:具有推导返回类型的函数'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()函数,代码将编译。 但是,我想在那里包含它。
您是否注意到如何从其他成员函数内部调用内联定义的成员函数,即使被调用者在类中比调用者更远? 之所以有效,是因为编译器采用了成员函数的内联定义,并将定义移到了类的底部,就在}
部分之后。 所以你实际上有一个隐含的前向声明。
对于using
声明等类型别名,情况并非如此。 这些声明确实存在于课堂上; 他们不能引用课程后面的声明或定义。
由于函数的返回值不能仅由声明推断,并且实际定义(推断返回值所需的东西)存在于类的末尾,因此using
别名无法编译。 除了直接声明函数的返回值之外,你无能为力。 或者将类型别名声明为具有所需类型,然后让函数使用该别名。
成员函数体是一个完整的类上下文 ,这意味着该类在那里被认为是完整的。 在成员函数的主体内,名称查找可以找到typedef的任何其他成员函数或数据成员 - 无论是在函数之前还是之后声明。
由于GetVector()
具有占位符类型,因此在实例化主体并推断返回类型之前,需要等到类完成。
但别名声明不是完整的类上下文。 你需要弄清楚什么VecInt
是在这一点上 ,而不必类是还没有全部完成。 由于GetVector()
需要首先完成类,所以这是行不通的。
您需要(a)显式指定GetVector()
的返回类型,(b)显式指定VecInt
,或(c)将GetVector()
移出此类(无论是将其作为自由函数还是将其移动到基类):
#include <vector>
struct TestBase {
template <typename T>
static auto GetVector() { return std::vector<T>(); }
};
struct Test : TestBase {
using VecInt = decltype(GetVector<int>());
VecInt x;
};
中间typedef可以帮忙吗? 就像是:
#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;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.