简体   繁体   English

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

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

I'm trying to use a property system in a class. 我正在尝试在类中使用属​​性系统。

A property has the corresponding member pointer, a name and an int (from an enum) to uniquely identify it. 属性具有相应的成员指针,名称和int(来自枚举)以唯一标识它。

Here is the code that defines a property: 以下是定义属性的代码:

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;
};

I create properties by calling this function: 我通过调用这个函数来创建属性:

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

My goal is to define properties for a class like this: 我的目标是为类定义属性,如下所示:

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;
};

I would like to be able to uncomment the line that declares m_propertyManager . 我希望能够取消注释声明m_propertyManager的行。 The problem is that this doesn't compile. 问题是这不能编译。 In g++, I get: 在g ++中,我得到:

error: use of 'static constexpr auto User::Properties()' before deduction of 'auto' 错误:在扣除'auto'之前使用'static constexpr auto User :: Properties()'

In Visual Studio 2015, I get: 在Visual Studio 2015中,我得到:

error C3779: 'User::UserProperties': a function that returns 'auto' cannot be used before it is defined 错误C3779:'User :: UserProperties':返回'auto'的函数在定义之前不能使用

How can I make this work? 我怎样才能做到这一点? It looks like a circulary dependency but I can't find how to make it work. 它看起来像一个循环依赖,但我找不到如何让它工作。 Here is the example: 这是一个例子:

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

I guess it is due to [class.mem]/6 . 我想这是由于[class.mem] / 6
It states that: 它指出:

A class is considered a completely-defined object type ([basic.types]) (or complete type) at the closing } of the class-specifier. 在类说明符的结束时,类被认为是完全定义的对象类型([basic.types])(或完整类型)。 [...] [...]

Note the last statement for your specific case: 请注意特定情况的最后一条陈述:

[...] Otherwise it is regarded as incomplete within its own class member-specification. [...]否则在其自己的类成员规范中被视为不完整。

Alias declarations are considered part of the member-specification and are not mentioned in the (let me say) exceptions to the rule: 别名声明被视为成员规范的一部分,并且在规则的(我说的)例外中没有提到:

[...] Within the class member-specification, the class is regarded as complete within function bodies, default arguments, exception-specifications, and default member initializers (including such things in nested classes). [...]在类成员规范中,该类在函数体,默认参数,异常规范和默认成员初始化器(包括嵌套类中的这类事物)中被视为完整。 [...] [...]

By reducing a bit further your example, we have this: 通过进一步减少你的例子,我们有:

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

int main() {}

The error is more or less the same. 错误或多或少相同。

At the using declaration, as mentioned above, the class is not considered a completely-defined type, thus are not its member functions. 在using声明中,如上所述,该类不被视为完全定义的类型,因此不是其成员函数。
Because of that, deduction for the return type of the member function can't take place and the using declaration cannot be satisfied. 因此,不能扣除成员函数的返回类型,并且不能满足使用声明。
Note that to deduce the return type the compiler must look at the definition of the function, that is at its body. 请注意,为了推断返回类型,编译器必须查看函数的定义,即函数的定义。

In other terms, it's not (conceptually) far from doing this: 换句话说,它(概念上)不是这样做的:

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

How can you evaluate the return type of a function that has not been defined yet? 如何评估尚未定义的函数的返回类型?
You cannot and the code above doesn't work indeed. 你不能和上面的代码确实不起作用。

The fact that the member function is a constexpr one doesn't change anything in this case. 成员函数是constexpr的事实在这种情况下不会改变任何东西。


As mentioned in the comments to the question, you can explicitly specify the return type by means of a trailing return type to work around the issue. 正如对问题的评论中所提到的,您可以通过尾随返回类型显式指定返回类型以解决此问题。
In that case, a definition is no longer required and you can get the return type out of the declaration. 在这种情况下,不再需要定义,您可以从声明中获取返回类型。 Actually, there will be no deduction at all for the return type. 实际上,返回类型根本不会有任何扣除。

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

相关问题 如何指定返回类的 constexpr 函数的类型(不使用 auto 关键字) - How to specify type of a constexpr function returning a class (without resorting to auto keyword) constexpr函数不返回constexpr值吗? - constexpr function not returning constexpr value? 使用静态constexpr成员函数返回类内部的auto - use of a static constexpr member function returning auto inside class 将模板化的constexpr传递给函数来推断自动对象的类型 - Passing templated constexpr to function inferring type of auto object constexpr函数返回字符串文字 - constexpr function returning string literal 返回constexpr的函数无法编译 - Function returning constexpr does not compile 带get的数据结构,返回constexpr(C ++) - Data structure with get, returning a constexpr (C++) 使用 constexpr + auto 作为返回和参数类型的奇怪类型推导 - Weird type deduction using constexpr + auto as return and parameter type 为什么在constexpr函数中允许返回对const指针的引用,但不返回副本? - Why is returning a reference to const pointer allowed in constexpr function, but not returning a copy? 是否可以为constexpr函数定义类型别名 - Is it possible to define type alias to constexpr function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM