Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If my class is a literal class then is it redundant to declare an object of my class as constexpr?

Tags:

c++

oop

constexpr

I have a constexpr class Debug:

struct Debug {
  constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
  bool a, b, c;
  constexpr bool get() const { return a; }
};

int main() {
  Debug dbg(true, false, false); // is dbg constexpr object?
  constexpr Debug dbg2(0, 0, 0); // is constexpr redundant here?
}

As you can see dbg is a constexpr object because it is initialized with a constexpr constructor so if I qualify it by a constexpr what is the point in that?

  • I don't know the difference between dbg and dbg2. Thank you.
like image 931
Maestro Avatar asked Jul 06 '19 22:07

Maestro


People also ask

What does constexpr mean in C++?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.

Can constexpr functions call non constexpr functions?

A call to a constexpr function produces the same result as a call to an equivalent non- constexpr function , except that a call to a constexpr function can appear in a constant expression. The main function cannot be declared with the constexpr specifier.

Where is constexpr defined?

constexpr stands for constant expression and is used to specify that a variable or function can be used in a constant expression, an expression that can be evaluated at compile time. The key point of constexpr is that it can be executed at compile time.

Can constexpr throw exception?

Even though try blocks and inline assembly are allowed in constexpr functions, throwing exceptions or executing the assembly is still disallowed in a constant expression.


1 Answers

There is a major difference: only dbg2 can be used where a constant expression is required. As an example, consider the upcoming C++20 feature that allows arbitrary non-type template parameters:

template <Debug> void f() { }

With the above definition, f<dgb2>() will compile, while f<dgb>() will not.

f<dgb>();
<source>:7:29: note:   template argument deduction/substitution failed:

<source>:13:12: error: the value of 'dbg' is not usable in a constant expression
   13 |   foo<dbg>();  // ERROR
      |            ^

<source>:10:9: note: 'dbg' was not declared 'constexpr'
   10 |   Debug dbg(true, false, false); // is dbg constexpr object?

live example on godbolt.org


This is also significant in C++11. You will be able to say:

template <bool> void g() { }
g<dgb2.a>();

But not:

g<dgb.a>();

live example on godbolt.org

like image 102
Vittorio Romeo Avatar answered Oct 15 '22 07:10

Vittorio Romeo