公开类型的template-template参数

Tom*_*Tom 3 c++ templates metaprogramming

我有一个取决于模板template参数的类型

template<typename X_, template<typename, typename> class Y_>
struct A { /*...*/ };
Run Code Online (Sandbox Code Playgroud)

我用工厂函数构造的:

template<typename X_, template<typename, typename> class Y_>
A<X_, Y_> make() {
    return A<X_, Y_> { /*...*/ };
};
Run Code Online (Sandbox Code Playgroud)

现在,我想添加一个工厂函数,该函数接受一个Aby引用并分配给它,而无需重新声明其模板参数:

template<typename A_>
void make(A_& a) {
    a = make<typename A_::X, typename A_::Y>();
}
Run Code Online (Sandbox Code Playgroud)

我添加了两个模板别名A来实现此目的:

template<typename X_, template<typename, typename> class Y_>
struct A { 
    using X = X_;
    template <typename... T>
    using Y = Y_<T...>;
    /* ... */ 
};
Run Code Online (Sandbox Code Playgroud)

然后我尝试编译:

A<int, std::vector> v;
make(v);
Run Code Online (Sandbox Code Playgroud)

产生,请参阅Godbolt

<source>: In instantiation of 'void make(A_&) [with A_ = A<int, std::vector>]':
<source>:24:11:   required from here
<source>:18:9: error: 'typename A<int, std::vector>::Y' names 'template<class ... T> using Y = class std::vector<T ...>', which is not a type

   18 |     a = make<typename A_::X, typename A_::Y>();

      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我不明白为什么GCC 9.2与我不同意Y这种类型。我应该如何正确地将意图传达给编译器?

Jar*_*d42 5

不是,typename但是template您应该使用:

template<typename A_>
void make(A_& a) {
    a = make<typename A_::X, A_::template Y>();
}
Run Code Online (Sandbox Code Playgroud)

此外

template<typename X_, template<typename, typename> class Y_>
struct A { 
    using X = X_;
    template <typename... T>
    using Y = Y_<T...>;
    /* ... */ 
};
Run Code Online (Sandbox Code Playgroud)

Y并且Y_不是等效的,您需要

template <typename T1, typename T2>
using Y = Y_<T1, T2>;
Run Code Online (Sandbox Code Playgroud)

而且我认为这仅是因为C ++ 17之后它们才是等效的。

演示版