Почему этот конструктор с переменными аргументами шаблона не совпадает? - PullRequest
1 голос
/ 22 октября 2011

У меня реализован конвейер обработки, но я бы хотел улучшить его следующим образом:

#include <iostream>

// buffers
struct src{}; struct b1{}; struct snk{};
// filters
struct f1
{
    f1( const src &, b1 & ) { std::cout << "f1( src, b1 )" << std::endl; }
};
struct f2
{
    f2( const b1 &, snk & ) { std::cout << "f2( b1, snk )" << std::endl; }
};
// the pipeline
template< typename... Filters >
struct pipeline
{
    template< typename LastB >
    pipeline( const LastB & )
    {}
};
template < typename T1, typename... T >
struct pipeline< T1, T... > : pipeline< T... >
{
    template< typename... Buffs, typename Bin, typename Bout >
    pipeline( Buffs &... buffs, Bin & bin, Bout & bout ) :
        pipeline< T... >( buffs..., bin ),
        filter( bin, bout )
    {
    }

    T1 filter;
};

int main()
{
    src ba; b1  bb; snk bc;

    pipeline< f1 > p1( ba, bb );
    pipeline< f1, f2 > p2( ba, bb, bc ); // the problem is in this line!
}

К сожалению, приведенный выше пример вызывает следующие ошибки:

sda_variadic.cpp: In function 'int main()':
sda_variadic.cpp:40:39: error: no matching function for call to 'pipeline<f1, f2>::pipeline(src&, b1&, snk&)'
sda_variadic.cpp:40:39: note: candidates are:
sda_variadic.cpp:26:5: note: template<class ... Buffs, class Bin, class Bout> pipeline<T1, T ...>::pipeline(Buffs& ..., Bin&, Bout&)
sda_variadic.cpp:23:8: note: constexpr pipeline<f1, f2>::pipeline(const pipeline<f1, f2>&)
sda_variadic.cpp:23:8: note:   candidate expects 1 argument, 3 provided
sda_variadic.cpp:23:8: note: constexpr pipeline<f1, f2>::pipeline(pipeline<f1, f2>&&)
sda_variadic.cpp:23:8: note:   candidate expects 1 argument, 3 provided

В чем причина этой ошибки?
Как это исправить?

Просто небольшое объяснение. Я ожидаю, что в приведенном выше примере сначала будет создан объект неспециализированной pipeline<>( snk ), затем специализированный объект pipeline< f1 >(b1,snk), а затем специализированный объект pipeline< f1, f2 >(src,b1,snk).
Кстати, обратите внимание, что приведенный выше пример работает для 1 фильтра (pipeline< f1).

1 Ответ

4 голосов
/ 22 октября 2011
template< typename... Buffs, typename Bin, typename Bout >
pipeline( Buffs &... buffs, Bin & bin, Bout & bout ) :
    pipeline< T... >( buffs..., bin ),
    filter( bin, bout )
{
}

Поскольку пакет функциональных параметров (Buffs) не находится в последней позиции, он не может быть выведен.От 14.8.2.1 Вывод аргументов шаблона из вызова функции [temp.deduct.call] параграф 1:

  1. [...] Для пакета параметров функции, который не встречается в концеиз списка объявлений-параметров тип пакета параметров является не выводимым контекстом.[...]

Поскольку вы не можете явно передать параметры шаблона конструктору, его нельзя вызвать вообще (хотя это и не имеет значения для вашей проблемы).

Я бы порекомендовал использовать std::tuple для манипулирования переменными аргументами, так что вы вызываете конструктор следующим образом: pipeline(std::forward_as_tuple(b0, b1, b2), in, out) и пустой кортеж будет передан на последний этап.

...