Можно ли через variadic tamplates (или как-то еще) инициализировать массив в классе?
Например, как-нибудь так:
typedef bool (*fnCheck)(Object1&, Object2&);
template<fnCheck ... A>
class Foo
{
public:
Foo() : array(A...) {} // error
bool check() {
// перебор массива, например
}
private:
fnCheck array[sizeof...(A)];
};
// и вот так использовать:
Foo<fn1, fn2, fn3> checker1;
Foo<fn2, fn3> checker2;
Foo<fn3, fn2, fn4, fn6> checker2;
Update
Нашел способ обернуть массив в структуру, вот так —
http://ideone.com/NbRQEu
Не очень красиво, но вполне приемлемо, пока других вариантов нет.
Здравствуйте, koenjihyakkei, Вы писали:
K>Можно ли через variadic tamplates (или как-то еще) инициализировать массив в классе?
K>Например, как-нибудь так:
K>K>template<fnCheck ... A>
K>class Foo
K>{
K>public:
K> Foo() : array(A...) {} // error
K>private:
K> fnCheck array[sizeof...(A)];
K>};
K>
Во-первых, достаточно вместо
array(A...) написать
array{A...}.
Во-вторых, тебе точно нужен в каждом экземпляре Foo<...> с одинаковыми шаблонными параметрами свой уникальный массив? Он у тебя меняется? Почему он вообще не сделан статическим constexpr членом класса? Незачем ведь что-то инициализировать в конструкторе, если у всех Foo<c1, c2, c3> должен иметься один и тот же массив с содержимым {c1, c2, c3}, вместо этого можно иметь один массив, инициализированный ещё на этапе компиляции.
В-третьих, зачем вообще массив?
bool check() {
for (auto&& checker : {A...})
if (!checker())
return false;
return true;
}
Здравствуйте, koenjihyakkei, Вы писали:
K>Можно ли через variadic tamplates (или как-то еще) инициализировать массив в классе?
Что-то как-то запутанно. Если нужен массив указателей на функции, то предполагается использовать его во время исполнения программы и тогда variadic template выглядит лишним. Достаточно
http://en.cppreference.com/w/cpp/utility/initializer_list
using fnCheck = bool (*)(Object1&, Object2&);
class Foo
{
public:
Foo(std::std::initializer_list<fnCheck> checks) : checks_(checks) {}
bool check()
{
for (auto& fn : checks_)
{
fn(obj1, obj2);
}
}
private:
std::vector<fnCheck> checks_;
};
Foo checker1({ fn1, fn2, fn3 });
Если указатели на функции доступны на этапе компиляции как variadic template, то зачем их еще дополнительно хранить в массиве:
using fnCheck = bool (*)(Object1&, Object2&);
template<fnCheck ... A>
class Foo
{
public:
bool check()
{
do_check<A...>();
}
private:
template<fnCheck Head, FnCheck... Tail>
bool do_check()
{
return Head(obj1, obj2) && do_check<Tail>();
}
bool do_check() { return true; }
};
Foo<fn2, fn3> checker2;
Код не проверял, просто идея.