set static variable in function only once
Asked Answered
H

3

6

So I was wondering if it is possible to set a static variable inside a function scope only once. For example consider this function:

void projectPointIntoPlane(const Affine3f& plane2xy, Vector3f& p)
{ 
  static Matrix3f P;
  P << Vector3f::UnitX(), Vector3f::UnitY(), Vector3f::Zero();

  p = plane2xy.inverse() * P * plane2xy * p;
}

I would like to set P only once and not at every function call, how can I achive this?

Hydrobomb answered 11/8, 2018 at 22:42 Comment(3)
I was going to upvote....but then I noticed your rep was 0xff.....jk +1Proscenium
not sure what you mean...Hydrobomb
You had exactly 255 reputation before I upvotedProscenium
W
8

Instead of declaring P and thereafter initializing it separately, you can initialize it in the declaration, using the finished() method of CommaInitializer:

static const Matrix3f P =
    (Matrix3f() << Vector3f::UnitX(), Vector3f::UnitY(),
     Vector3f::Zero()).finished();

With this approach, you can also declare P as const.

Willey answered 11/8, 2018 at 22:51 Comment(2)
to me this looks way cleaner than what igor or rakete propose, but it is not so general...Hydrobomb
@Hydrobomb indeed, this would be the idiomatic Eigen approach. If I didn't know this was Eigen (and did not have access to the fit-for-purpose finished() method) and would need general solution, Igor Tandetnik's lambda is a good approach.Willey
A
5

You could use a lambda that returns the right value. Since it's in the initialization expression, it's only called once:

void projectPointIntoPlane(const Affine3f& plane2xy, Vector3f& p)
{
    static Matrix3f P = []{
        Matrix3f P;
        P << Vector3f::UnitX(), Vector3f::UnitY(), Vector3f::Zero();
        return P;
    }();

    p = plane2xy.inverse() * P * plane2xy * p;
}
Anxious answered 12/8, 2018 at 4:46 Comment(0)
T
4

Something along these lines:

static Matrix3f P;
static bool dummy = (
  (P << Vector3f::UnitX(), Vector3f::UnitY(), Vector3f::Zero()),
  true);
Thigmotaxis answered 11/8, 2018 at 22:43 Comment(2)
Or fold the initialization in the lambda and then return the object.Mahratta
I just noticed that at the moment this is more generic, if for example P is a template the lambda wont work.Hydrobomb

© 2022 - 2024 — McMap. All rights reserved.