тут, обратите внимание на type0/type1 и arg0/arg1.
type0/type1 могут быть как классовыми типами, так и подами/фундаментальными.
во время кодогенерации нет возможности определить, чем на самом деле являются типы, и, следовательно, нет возможности сгенерировать нужный способ инициализации.
предложения?
спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: использовать аллокатор только для тех типов, которые это
template<class T, class A, bool WithA> struct with_allocator_base;
template<class T, class A> struct with_allocator_base<T,A,true>
{
T var;
explicit with_allocator_base(A& a) : var(a) {}
T& operator() { return var; }
};
template<class T, class A> struct with_allocator_base<T,A,false>
{
T var;
explicit with_allocator_base(A& a) {}
T& operator() { return var; }
};
template<class T, class A> struct with_allocator : with_allocator_base<T,A, has_constructor<T,A>::value >
{
typedef with_allocator_base<T,A, is_constructible_from<T,A>::value > base;
explicit with_allocator(A& a) : base(a) {}
};
Если типы копи-конструируемые, то можно и проще
template<class T, class A> auto make(A& a) -> enable_if< is_constructible<T,A>::value, T >::type { return T(a); }
template<class T, class A> auto make(A& a) -> enable_if<!is_constructible<T,A>::value, T >::type { return T( ); }
......
type0 arg0 = make<type0>(alloc);
type1 arg1 = make<type1>(alloc);
Перекуём баги на фичи!
Re[2]: использовать аллокатор только для тех типов, которые это
К>template<class T, class A> struct with_allocator : with_allocator_base<T,A, has_constructor<T,A>::value > {
К> typedef with_allocator_base<T,A, is_constructible_from<T,A>::value > base;
К> explicit with_allocator(A& a) : base(a) {}
К>};
К>
в первой строке ты наследуешь конкретный with_allocator_base. но во второй строке ты определяешь тип base, который, возможно специализируется по другому условию, ибо: 'is_constructible_from<T,A>::value' и 'has_constructor<T,A>::value' — разные шаблоны. или тут опечатка?
и то, что ты выполняешь во второй и третьей строке, насколько я понимаю, можно заменить так?:
using with_allocator_base<T,A, has_constructor<T,A>::value>with_allocator_base;
Здравствуйте, niXman, Вы писали:
X>в первой строке ты наследуешь конкретный with_allocator_base. но во второй строке ты определяешь тип base, который, возможно специализируется по другому условию, ибо: 'is_constructible_from<T,A>::value' и 'has_constructor<T,A>::value' — разные шаблоны. или тут опечатка?
Опечатка, конечно. Я же испытывал на кошках — набросал эскиз в нотепаде и скомпилировал 2010 студией. После чего вспомнил, что велосипедирую, в 11 стандарте уже есть нужная метафункция, и переписал... но недопереписал
X>и то, что ты выполняешь во второй и третьей строке, насколько я понимаю, можно заменить так?: X>using with_allocator_base<T,A, has_constructor<T,A>::value>with_allocator_base;
Да. Потому что у меня основной компилятор — это VS2010, а С++11 это для души, и редкоиспользуемые фичи я не всегда вспоминаю; зато очень быстро печатаю десятью пальцами
На самом деле, всё проще: надо протащить SFINAE в конструкторЫ обёртки
template<class T> struct with_allocator
{
struct unspecified_type; // от греха подальше: чтобы никто не передавал второй параметр в конструктор
T var;
T& operator*() { return var; }
T const& operator*() { return var; }
template<class A>
explicit with_allocator(A& a,
typename enable_if< is_constructible<T,A&>::value, unspecified_type* >::type _ = nullptr)
: var(a)
{}
template<class A>
explicit with_allocator(A& a,
typename enable_if<!is_constructible<T,A&>::value, unspecified_type* >::type _ = nullptr)
{}
};