我面临的问题是,在我的应用程序中,在构造函数中初始化类成员的顺序很重要。因此,我需要使用笨拙的语法来获得我想要的行为。
这应该概述我的问题(见下面的代码):我想要我的
class Widget
包括
class WidgetSignals
从用户的角度来看。我不能使用继承,因为这需要我初始化继承的
WidgetSignals
在成员面前
elements
的
Widget
WidgetSignals公司
.
template<typename... Elems>
class WidgetSignals
{
WidgetSignals(const std::tuple<Elems...> elems)
: // initialize members using elems
{}
// members ...
};
template<typename... Elems>
class Widget : public WidgetSignals<Elems...>
{
std::tuple<Elems...> elements;
Widget(vec4 quad)
: WidgetSignals<Elems...>(elements) // uh-oh! elements are not initialized yet!
, elements(initalizeElements(quad))
};
下面是我以前解决这个问题的方法:
使用中介帮助程序类:
template<typename... Elems>
class Widget : public WidgetSignals<Elems...>
{
std::tuple<Elems...> elements;
struct Data
{
Data(vec4 quad)
: elems(initializeElements(quad)) // initialize elements here
{}
std::tuple<Elems...> elems;
};
Widget(Data data)
: WidgetSignals<Elems...>(data.elems) // bingo!
, elements(data.elems)
{}
};
封装
WidgetSignals公司
WidgetSignals公司
'小部件中的成员:
template<typename... Elems>
class Widget
{
std::tuple<Elems...> elements;
WidgetSignals<Elems...> signals;
Widget(vec4 quad)
: elements(initializeElements(quad))
, signals(elements) // initialized after elements because of order of member declaration
{}
// WidgetSignal member references
const typename WidgetSignals<Elems...>::SignalType& enter = signals.enter;
const typename WidgetSignals<Elems...>::SignalType& leave = signals.leave;
// ... remaining members
};
有了这两个解决方案,我就可以使用
通过一个
小装置
Widget widget(vec4(0, 0, 20, 5));
foo(widget.enter);
但这两种解决方案都相当繁琐和混乱,所以我真的希望有更好的语法,比如:
using signals;
或
using signals::enter;
小装置
.
using WidgetSignals<Elems...>::enter;
实际上是有效的,但前提是
已经继承自
WidgetSignals公司