Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can have definition variable of non-literal type in constexpr function body c++14?

I think that in C++14 more restrictives are removed from constexpr. But according N3797 7.1.5 3-punct:


The definition of a contexpr function shall satisfy the following constraints:

  • it shall not be virtual
  • its return type shall be a literal type;
  • each of its parameters types shall be a literal type;
  • its function-body shall be = delete, = default, or a compound-statement that does not contain:
  • an asm-definition,
  • a goto statement,
  • a try-block, or
  • a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.

I know why static, thread storage duration variables are disallowed, but I don't see any reason, why ONLY allowed definition of a variable of literal type ?

Or I'm not understand the standard.

I'm not sure, but according standard following errors should be created even C++14:

struct point{
constexpr point(): x(0), y(0){}
constexpr point(int x_, int y_): x(x_),y(y_){}
constexpr int hypot()const { return x*x + y*y; }
int x,y;
};

constexpr int hypot(int x, int y) {  
   point p{x,y}; //error, because p - is not literal type.
   return p.hypot();
}

// error, because return type is not literal.
constexpr point  getPoint(int x, int y) { return {x,y}; }

// error, because parameter is not literal.
constexpr int hypot(point p) { return p.hypot(); }

Q: If really above errors would happen, why these restrictions are not removed?

like image 800
Khurshid Avatar asked Feb 14 '14 19:02

Khurshid


1 Answers

literal type is defined in 3.9/10:

A type is a literal type if it is:

  • void; or

  • a scalar type; or

  • a reference type; or

  • an array of literal type; or

  • a class type (Clause 9) that has all of the following properties:

    • it has a trivial destructor,

    • it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and

    • all of its non-static data members and base classes are of non-volatile literal types

So your struct point is a literal type and your sample code is valid C++1y.

As to why constexpr functions are restricted to variables of literal type, they are the only types that are guaranteed to be interpretable at compile time.

like image 158
Casey Avatar answered Oct 11 '22 21:10

Casey