Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any reason to declare constexpr for a function that returns void?

Tags:

c++

c++11

Here is what I read: using alias for static member functions?

In the answer I see a suggestion to use constexpr. What is the reason to use constexpr for void functions.

Please demonstrate a simple use case. I am new to constexpr so in complex examples I will not understand the gist.

like image 276
Narek Avatar asked Feb 12 '16 06:02

Narek


People also ask

Why is constexpr needed?

A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations. And when a value is computed at compile time instead of run time, it helps your program run faster and use less memory.

Does constexpr improve performance?

Understanding constexpr Specifier in C++ constexpr is a feature added in C++ 11. The main idea is a performance improvement of programs by doing computations at compile time rather than run time.

Do constexpr functions have to be defined in header?

Constexpr functions are implicitly inline, which means they are suitable to be defined in header files. Like any function in a header, the compiler is more likely to inline it than other functions.

Does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later. So, what does constexpr mean?


2 Answers

Rahul's answer cites the standard paragraph which allow void constexpr functions, but it doesn't give a use-case. One use-case that comes to my mind would be to have a constexpr class, and as usual factor out behavior common to method in helper methods. The standard explicitly mentions function doing checks, e.g. assertions. I don't have a concrete example at hand, but I can imagine something like

class A
{
public:
    constexpr X doSomething(Y arg1) {
        checkInvariant();
        constraintOnYArgument(arg1);
        // ...
        checkInvariant();        
    }

    constexpr X doSomethingElse(Y arg1) {
        checkInvariant();
        constraintOnYArgument(arg1);
        // ...
        checkInvariant();        
    }

private:
    constexpr void constraintOnYArguments(Y arg) {
    }

    constexpr void checkInvariant() {
        // some checks
        if (!some condition) {
            throw std::logic_error("Oh no!");
        }
    }
};
like image 171
Jens Avatar answered Oct 05 '22 01:10

Jens


As per the C++ 14 standard, void is a literal type

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.

From here:

An arbitrary expression-statement is permitted, in order to allow calls to functions performing checks and to allow assert-like constructs. void also becomes a literal type, so that constexpr functions which exist only to perform such checks may return void.

like image 31
Rahul Tripathi Avatar answered Oct 05 '22 01:10

Rahul Tripathi