Инициализация массива класса через шаблон
От: koenjihyakkei Россия  
Дата: 01.09.15 03:02
Оценка:
Можно ли через 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
Не очень красиво, но вполне приемлемо, пока других вариантов нет.
Отредактировано 01.09.2015 3:39 koenjihyakkei . Предыдущая версия .
Re: Инициализация массива класса через шаблон
От: watchmaker  
Дата: 01.09.15 08:04
Оценка:
Здравствуйте, 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;
    }
Отредактировано 01.09.2015 8:10 watchmaker . Предыдущая версия .
Re: Инициализация массива класса через шаблон
От: PM  
Дата: 01.09.15 08:23
Оценка:
Здравствуйте, 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;


Код не проверял, просто идея.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.