Передача ссылок на Variadic шаблоны

Я работаю над библиотекой событий и столкнулся с проблемой с шаблонами Variadic.

Все работает очень хорошо, за исключением того факта, что я не могу передавать ссылки в качестве параметров ...

Вот очень упрощенный пример, написанный для раскрытия моей проблемы.

struct DelayedSignal 
{   
    ~DelayedSignal ()
    { std::cout << "~DelayedSignal CLOSE" << std::endl; }

    template<class C, class... Args>
    DelayedSignal ( void(C::*func)(Args...), C& obj )
    { std::cout << "DelayedSignal INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }

    template<class C, class... Args>
    DelayedSignal ( void(C::*func)(Args...), C& obj, Args... args )
    {
        std::cout << "DelayedSignal INIT - 04 - pointer to method & pointer to class instance & arguments (Arg num: " << sizeof...(Args) << ")" << std::endl;
    }
};

template<class... ArgsBis>
struct DelayedSignal_DebugHelper 
{
    ~DelayedSignal_DebugHelper ()
    { std::cout << "~DelayedSignal_DebugHelper CLOSE" << std::endl; }

    template<class C, class... Args>
    DelayedSignal_DebugHelper ( void(C::*func)(Args...), C& obj )
    { std::cout << "DelayedSignal_DebugHelper INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }

    template<class C, class... Args>
    DelayedSignal_DebugHelper ( void(C::*func)(Args...), C& obj, ArgsBis... args ) // Need to use ArgsBis instead of Args to make it work
    {
        std::cout << "DelayedSignal_DebugHelper INIT - 04 - pointer to method & pointer to class instance & arguments (Arg num: " << sizeof...(Args) << ")" << std::endl;
    }
};


template < class Tr, class... Args >
struct Signal
{
    void fire ( Args... args ) { std::cout << "Signal::fire::" << sizeof...(Args) << std::endl; }
};

struct Klass {};


int main()
{
    std::string str1("Blop");   // Will be used as reference
    Klass k;                    // Will be used as reference

    Signal<void, Klass&> signal_01;
    Signal<void, std::string&> signal_02;

    std::cout << "====== DelayedSignal :: needed for production purpose ===============" << std::endl;

    // OK
    DelayedSignal test01(&Signal<void, std::string&>::fire, signal_02);
    // HERE IS THE PROBLEM
    //DelayedSignal test02(&Signal<void, std::string&>::fire, signal_02, str1);

    // OK
    DelayedSignal test03(&Signal<void, Klass&>::fire, signal_01);
    // HERE IS THE PROBLEM
    //DelayedSignal test04(&Signal<void, Klass&>::fire, signal_01, k);

    std::cout << "====== DelayedSignal_DebugHelper :: used only for debug purpose ======" << std::endl;

    // OK
    DelayedSignal_DebugHelper<std::string&> test05(&Signal<void, std::string&>::fire, signal_02);
    // OK
    DelayedSignal_DebugHelper<std::string&> test06(&Signal<void, std::string&>::fire, signal_02, str1);

    // OK
    DelayedSignal_DebugHelper<Klass&> test07(&Signal<void, Klass&>::fire, signal_01);
    // OK
    DelayedSignal_DebugHelper<Klass&> test08(&Signal<void, Klass&>::fire, signal_01, k);

    return 1;
}

Поскольку я регистрирую все экземпляры DelayedSignal в одном экземпляре std :: list, я бы хотел избежать использования шаблона в самом классе, поэтому вместо этого я использую шаблоны в конструкторах. Я мог бы также использовать чистый виртуальный класс в качестве основы для всех DelayedSignal и зарегистрировать указатели на виртуальный класс в std :: list, но я думаю, что лучше всего свести к минимуму использование виртуальных методов, и я действительно заинтригован этой проблемой ...

Как вы можете видеть в этом примере, test02 и test04 возвращают ошибки, если они активированы. DelayedSignal_DebugHelper почти идентичен DelayedSignal, за исключением того факта, что он использует ArgsBis (аргумент шаблона класса) в последнем конструкторе вместо шаблона Args (аргумент шаблона метода), иначе он не работает (как с DelayedSignal). Аргументы принимаются в void (C :: * func) (Args ...) , но не в ArgsBis ... args , несмотря на то, что они находятся в одном объявлении конструктора .

Насколько мне известно, проблем без ссылок ( DelayedSignal test04 (& Signal :: fire, signal_01, k); например) или с несколькими параметрами (или нет), пока нет ссылок.

Есть ли способ исправить эту проблему?

Спасибо.

10
задан TonyK 4 April 2011 в 10:57
поделиться