constexpr non-static member functions of non-literal types

1,402 views
Skip to first unread message

dyp

unread,
Dec 16, 2014, 3:30:02 PM12/16/14
to std-dis...@isocpp.org
Are constexpr non-static member functions allowed as members of
non-literal types?

The proposal N3652 "Relaxing constraints on constexpr functions" still
contains a restriction in [dcl.constexpr] (7.1.5)/8:

"The class of which <strike>that</strike> a constexpr function is a
member shall be a literal type (3.9)."

However, the proposed resolution of CWG 1684 removed that sentence
entirely. The rationale given is:

"The previous version of this wording made clear that the restriction
on the class type applied only to non-static member functions;
consequently, the new formulation has inadvertently banned static
constexpr member functions of non-literal classes."

It is not clear to me if allowing constexpr non-static member
functions for non-literal classes is intended to be allowed. I cannot
find any other restriction in the Standard drafts. Furthermore, both
clang++ and g++ tip of trunk refuse them:

#include <string>
struct X {
std::string s;
constexpr int foo() { return 42; }
};
int main() {}


clang++: error: non-literal type 'X' cannot have constexpr members

g++: error: enclosing class of constexpr non-static member function
‘int X::foo()’ is not a literal type


Are they allowed? If not, where is it specified that they're illegal?


Thanks and kind regards,

dyp

Ville Voutilainen

unread,
Dec 16, 2014, 3:51:13 PM12/16/14
to std-dis...@isocpp.org
I have forwarded this to the Core Working Group. I'll let you know what they
respond with.

Richard Smith

unread,
Dec 16, 2014, 6:13:45 PM12/16/14
to std-dis...@isocpp.org
(Copied from my reply in CWG)

On Tue, Dec 16, 2014 at 12:29 PM, dyp <dyp...@gmx.net> wrote:
Are constexpr non-static member functions allowed as members of
non-literal types?

Yes.
 
The proposal N3652 "Relaxing constraints on constexpr functions" still
contains a restriction in [dcl.constexpr] (7.1.5)/8:

"The class of which <strike>that</strike> a constexpr function is a
member shall be a literal type (3.9)."

However, the proposed resolution of CWG 1684 removed that sentence
entirely. The rationale given is:

"The previous version of this wording made clear that the restriction
on the class type applied only to non-static member functions;
consequently, the new formulation has inadvertently banned static
constexpr member functions of non-literal classes."

As frequently happens, core discussion resulted in a different resolution than the one suggested in the initial write-up of the issue. We decided that the restriction is without merit; it was somewhat inconsistent that:

  constexpr int f(NonLiteral &x) { return 0; }

is valid, but

  struct NonLiteral {
    NonLiteral();
    constexpr int f() { return 0; }
  };

is not. Pointer and reference parameters to constexpr functions need not point or refer to constexpr objects, and the implicit 'this' parameter shouldn't be special here. (And 'literal type' is really just a proxy for 'there may exist constant expressions of this type' that enables us to require diagnostics.)
 
It is not clear to me if allowing constexpr non-static member
functions for non-literal classes is intended to be allowed. I cannot
find any other restriction in the Standard drafts. Furthermore, both
clang++ and g++ tip of trunk refuse them:

#include <string>
struct X {
    std::string s;
    constexpr int foo() { return 42; }
};
int main() {}


clang++: error: non-literal type 'X' cannot have constexpr members

g++: error: enclosing class of constexpr non-static member function
‘int X::foo()’ is not a literal type

Clang trunk now accepts this code.
 
Are they allowed? If not, where is it specified that they're illegal?


Thanks and kind regards,

dyp

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.

Reply all
Reply to author
Forward
0 new messages