考虑以下代码:
#include <iostream>
struct A {
A(int n, char c, bool b)
/* : some complex initialization list that you don't want to repeat. */
{initialize();}
A(int n) : A(n, default_char, default_bool) {}
A(char c) : A(default_int, c, default_bool) {} // Do not want initialize() called!
A(bool b) : A(default_int, default_char, b) {}
A(int n, char c) : A(n, c, default_bool) {}
A(int n, bool b) : A(n, default_char, b) {} // Do not want initialize() called!
A(char c, bool b) : A(default_int, c, b) {}
private:
static const int default_int = 3;
static const char default_char = 't';
static const bool default_bool = true;
void initialize() {std::cout << "A ctor.\n";}
};
int main() {
A a(5,'a',false);
A b(5);
A c('a');
A (5,'a');
A (5,false);
A ('a',false);
}
假设我不希望为某些构造函数调用initialize();
(例如在代码中声明)。如何避免这种情况而不重复&#34;复杂的初始化列表&#34; A(int,char,bool)
的构造函数(以避免将来的维护问题)?
答案 0 :(得分:6)
您可以为您的类提供一个私有构造函数,所有公共构造函数都委托给它。这里,第一个参数决定是否初始化:
private:
A(bool do_initialize, int n, char c, bool b)
/* initialisers */
{ if (do_initialize) initialize(); }
public:
A(int n, char c, bool b) : A(true, n, c, b) {}
A(int n) : A(true, n, default_char, default_bool) {}
A(char c) : A(false, default_int, c, default_bool) {} // Do not want initialize() called!
A(bool b) : A(true, default_int, default_char, b) {}
A(int n, char c) : A(true, n, c, default_bool) {}
A(int n, bool b) : A(false, n, default_char, b) {} // Do not want initialize() called!
A(char c, bool b) : A(true, default_int, c, b) {}
答案 1 :(得分:1)
大多数解决方案请参阅this question。一旦我们有了这个,我们可以:
template <typename DoInit>
A(int n, char c, bool b, DoInit do_init)
/* : some complex initialization list that you don't want to repeat. */
{
maybe_initialize(DoInit{});
}
void maybe_initialize(std::false_type ) { }
void maybe_initialize(std::true_type ) {
/* stuff */
}
因此,我们有做想要初始化的一般情况:
template <typename ... Ts, typename std::enable_if_t<detail::is_included<std::tuple<Ts...>, std::tuple<Year, Month, Day>> ::value>* = nullptr>
A(Ts... ts) :
A(get_or_default<int>(std::tie(ts...)),
get_or_default<char>(std::tie(ts...)),
get_or_default<bool>(std::tie(ts...)),
std::true_type{})
{}
然后是我们不想要它的一堆案例:
A(char c)
: A(default_int, c, default_bool, std::false_type{})
{ }
A(int n, bool b)
: A(n, default_char, b, std::false_type{})
{ }
如果存在 lot 这样的情况,您可以为可变参数模板构造函数添加类似的enable_if_t
条件。