Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
173 views
in Technique[技术] by (71.8m points)

c++ - Is there a specific reason why a trailing-return-type is not a complete-class context of a class?

Note that a trailing-return-type is not mentioned in [class.mem]p6

A complete-class context of a class is a

(6.1) function body,
(6.2) default argument,
(6.3) noexcept-specifier ([except.spec]),
(6.4) contract condition, or
(6.5) default member initializer

within the member-specification of the class. [?Note: A complete-class context of a nested class is also a complete-class context of any enclosing class, if the nested class is defined within the member-specification of the enclosing class. —?end note?]

[expr.prim.this]p2 also has a note about this:

If a declaration declares a member function or member function template of a class X, the expression this is a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifier-seq and the end of the function-definition, member-declarator, or declarator. It shall not appear before the optional cv-qualifier-seq and it shall not appear within the declaration of a static member function (although its type and value category are defined within a static member function as they are within a non-static member function). [?Note: This is because declaration matching does not occur until the complete declarator is known. —?end note?] [?Note: In a trailing-return-type, the class being defined is not required to be complete for purposes of class member access. Class members declared later are not visible. [?Example: ...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Because you don't want it.

 struct Test {
     auto foo() -> decltype(bar());
     auto bar() -> int;

     auto baz() -> decltype(qux());
     auto qux() -> decltype(baz());
 }; 

Now you need all sorts of rules explaining which of the above is allowed and which is not.

So why does the standard places noexcept-specifier in complete-class context? Wouldn't it allow essentially the same thing in code like this:

struct Test { 
    void foo() noexcept(noexcept(bar())); 
    void bar() noexcept(noexcept(foo())); 
};

?

It seems the standard doesn't address this well, and the compilers differ in treatment of this. Clang complains about the above code, but eats this:

struct Test { 
    void foo() noexcept(Test::b);
    static const bool b = true;
};

GCC complains about the second code too, but accepts code with the member declarations swapped. It seems it doesn't treat the noexcept specifier as complete-class context at all.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...