Привязка к шаблону - PullRequest
3 голосов
/ 31 мая 2019

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

Для этого я создал шаблон, который определяет шаблон псевдонима.

Если я использую этот шаблон привязки с конкретными типами, это работает хорошо. Но если я создаю экземпляр шаблона привязки с другим аргументом шаблона, gcc и clang предполагают, что псевдоним не является шаблоном шаблона. Я знаю, что это становится зависимым именем, но нет ничего похожего на typename двусмысленность для шаблонов.

С icc и msvc это работает нормально.

template<
    template<typename> typename Template 
>
class ATypeWhichNeedsATemplateTemplate
{
};

template<typename A, typename B>
class AComplexTemplate
{
};

template<
    template<typename...> typename ATemplate 
    ,typename... Args
>
class Binder {
public:
    template<typename T>
    using type = ATemplate<T, Args...>;
};

template<typename T>
class AClassWithBoundTemplate : public ATypeWhichNeedsATemplateTemplate<
    Binder<AComplexTemplate, T>::type
>
{    
};

см. На кресте

Кланг жалуется:

<source>:30:5: error: template argument for template template parameter must be a class template or type alias template

    Binder<AComplexTemplate, T>::type

    ^

gcc говорит что-то похожее:

<source>:31:1: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class> class Template> class ATypeWhichNeedsATemplateTemplate'

 >

 ^
<source>:31:1: note:   expected a class template, got 'Binder<AComplexTemplate, T>::type'

1 Ответ

3 голосов
/ 31 мая 2019

type является зависимым именем шаблона. Вы должны записать это как Binder<AComplexTemplate, T>::template type, т.е. e.:

template<typename T>
class AClassWithBoundTemplate : public ATypeWhichNeedsATemplateTemplate<
    Binder<AComplexTemplate, T>::template type
>
{    
};

Исправлен пример бога: https://godbolt.org/z/7nJtAU

...