Introduction
Let's introduce this simple example:
#include <cmath>
class X
{
public: // Members
/// A ^ B + A
int A;
/// A ^ B + B
int B;
public: // Specials
X(
const int & A,
const int & B
)
: A(A)
, B(B)
{
const auto Pow = static_cast<int>(std::pow(A, B));
this->A += Pow;
this->B += Pow;
}
};
Trivia
- Introduced class has two member variables:
A
andB
. - They take value of
A ^ B + A
andA ^ B + B
, respectively. - Both of them shares common complex initialization code (let's assume
std::pow
is complex).
Problem
I'd like to make both A
and B
members const
.
Question
How to do that without repeating complex initialization (ie avoid calling std::pow
twice)?
What I've tried
#include <cmath>
class X
{
public: // Members
/// A ^ B + A
const int A;
/// A ^ B + B
const int B;
public: // Helpers
struct Init
{
public: // Members
int A;
int B;
public: // Specials
Init(
const int & A,
const int & B
)
: A(A)
, B(B)
{
const auto Pow = static_cast<int>(std::pow(A, B));
this->A += Pow;
this->B += Pow;
}
};
public: // Specials
X(
const Init& Init
)
: A(Init.A)
, B(Init.B)
{};
X(
const int & A,
const int & B
)
: X(Init(
A,
B
))
{};
};
- Create
struct Init
that takes role of past version of classX
. - Make
X
membersconst
while keepInit
members nonconst
. - Use constructor delegation to redirect constructor arguments to
Init
. - Move non
const
member variables fromInit
toX
and make themconst
.- Note there is no
std::move
asint
is TriviallyCopyable.
- Note there is no
However, my solution seems overcomplicated. Any help would be appreciated.
No goals
- Make another
X
member variable that will store common code result (iestd::pow
). - Add another level of indirection outside
X
class (eg introduce base class forX
).
Note
Solutions can use newer versions of C++ than C++11.