Чтобы изменить принятый ответ, обратите внимание, что начиная с C ++ 11 вы можете делать очень аккуратные трюки. Например, ваша исходная проблема может быть решена с помощью лямбда-и делегирования конструкции следующим образом:
class MyReferenceClass {
public: /* Methods: */
MyReferenceClass()
: MyReferenceClass([](){
std::array<double, 3u> cs; /* Helper class, array or tuple */
computeImportantConstants(&cs[0u], &cs[1u], &cs[2u]);
return cs;
})
{}
const double importantConstant1;
const double importantConstant2;
const double importantConstant3;
private: /* Methods: */
MyReferenceClass(std::array<double, 3u> constants)
: ImportantConstant1(constants[0u])
, ImportantConstant2(constants[1u])
, ImportantConstant3(constants[2u])
{}
static void computeImportantConstants(double * out_const1,
double * out_const2,
double * out_const3);
}; /* class MyReferenceClass { */
Или, что еще лучше, переместите код инициализации из computeImportantConstants
в лямбду в конструкторе, если это возможно.
На практике использование лямбда-вызовов для инициализации константных членов является очень удобным трюком, особенно потому, что вы также можете связывать и / или передавать аргументы в лямбду. А использование делегирования конструкции помогает упростить инициализацию элементов, которые лучше всего инициализировать вместе или могут зависеть друг от друга.
Однако следует проявлять особую осторожность при использовании делегирования конструкции, поскольку порядок инициализации аргументов функции для вызова функции (или вызова конструктора) не определен, и в конечном итоге можно инициализировать вещи в неправильном порядке или способом, может привести к утечке ресурсов, если что-то не получится или возникнет исключение.