繁体   English   中英

无法获得返回constexpr auto的函数类型

[英]Unable to get type of function returning constexpr auto

我正在尝试在类中使用属​​性系统。

属性具有相应的成员指针,名称和int(来自枚举)以唯一标识它。

以下是定义属性的代码:

template<typename Class, typename T>
struct MemberProperty
{
    constexpr MemberProperty(T Class::*aMember, const char* aName, int aId)
    : member(aMember), name(aName), id(aId)
    {}

    T Class::*member;
    const char* name;
    int id;
};

我通过调用这个函数来创建属性:

template <typename Class, typename T>
constexpr auto makeProperty(T Class::*member, const char* name, int id) {
    return MemberProperty<Class, T>{member, name, id};
}

我的目标是为类定义属性,如下所示:

class User
{
public:
    enum PropertiesEnum
    {
        Property_Name
    };

    string m_name;

    static constexpr auto Properties() {
        return std::make_tuple(
            makeProperty(&User::m_name, "name", User::Property_Name)
        );
    }

    using PropertiesType = decltype(Properties());

    //PropertyManager<PropertiesType> m_propertyManager;
};

我希望能够取消注释声明m_propertyManager的行。 问题是这不能编译。 在g ++中,我得到:

错误:在扣除'auto'之前使用'static constexpr auto User :: Properties()'

在Visual Studio 2015中,我得到:

错误C3779:'User :: UserProperties':返回'auto'的函数在定义之前不能使用

我怎样才能做到这一点? 它看起来像一个循环依赖,但我找不到如何让它工作。 这是一个例子:

http://coliru.stacked-crooked.com/a/24e7f5ea7f83da6f

我想这是由于[class.mem] / 6
它指出:

在类说明符的结束时,类被认为是完全定义的对象类型([basic.types])(或完整类型)。 [...]

请注意特定情况的最后一条陈述:

[...]否则在其自己的类成员规范中被视为不完整。

别名声明被视为成员规范的一部分,并且在规则的(我说的)例外中没有提到:

[...]在类成员规范中,该类在函数体,默认参数,异常规范和默认成员初始化器(包括嵌套类中的这类事物)中被视为完整。 [...]

通过进一步减少你的例子,我们有:

struct S {
    auto f() {}
    using T = decltype(f());
};

int main() {}

错误或多或少相同。

在using声明中,如上所述,该类不被视为完全定义的类型,因此不是其成员函数。
因此,不能扣除成员函数的返回类型,并且不能满足使用声明。
请注意,为了推断返回类型,编译器必须查看函数的定义,即函数的定义。

换句话说,它(概念上)不是这样做的:

auto f();
using T = decltype(f());
int main() {}

如何评估尚未定义的函数的返回类型?
你不能和上面的代码确实不起作用。

成员函数是constexpr的事实在这种情况下不会改变任何东西。


正如对问题的评论中所提到的,您可以通过尾随返回类型显式指定返回类型以解决此问题。
在这种情况下,不再需要定义,您可以从声明中获取返回类型。 实际上,返回类型根本不会有任何扣除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM