c++ - 公开模板类型的模板参数

标签 c++ templates metaprogramming

我有一个依赖于模板模板参数的类型:

template<typename X_, template<typename, typename> class Y_>
struct A { /*...*/ };

我用工厂函数构造:

template<typename X_, template<typename, typename> class Y_>
A<X_, Y_> make() {
    return A<X_, Y_> { /*...*/ };
};

现在,我想添加一个工厂函数,它通过引用获取一个 A 并将其赋值给它,而无需重述其模板参数:

template<typename A_>
void make(A_& a) {
    a = make<typename A_::X, typename A_::Y>();
}

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

template<typename X_, template<typename, typename> class Y_>
struct A { 
    using X = X_;
    template <typename... T>
    using Y = Y_<T...>;
    /* ... */ 
};

然后我尝试编译:

A<int, std::vector> v;
make(v);

产生,see 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>();

      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

最佳答案

这不是 typename 而是 template 你应该使用:

template<typename A_>
void make(A_& a) {
    a = make<typename A_::X, A_::template Y>();
}

此外

template<typename X_, template<typename, typename> class Y_>
struct A { 
    using X = X_;
    template <typename... T>
    using Y = Y_<T...>;
    /* ... */ 
};

YY_ 不等价,你需要

template <typename T1, typename T2>
using Y = Y_<T1, T2>;

而且我认为只有在 C++17 之后它们才等价。

Demo

关于c++ - 公开模板类型的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57851073/

相关文章:

c++ - 运算符重载逻辑问题

c++ - 为什么 boost::any 没有 "getter"?

c++ - 在 C/C++ 中,是否可以通过使用指针更改 "important"内存地址的值来创建简单的恶意软件?

c++ - 在 Boost Spirit 中定义使用子解析器参数化的解析器

c++ - 在 C++ 中有没有办法将 "compare"为带有类型名的字符串?

c++ - QT C++ 中的淡出小部件

c++ - 为什么在 C++ 中构造函数被调用两次?

Ruby - 将变量传递给 eval 方法

Ruby 元编程 : instance_eval and class_eval

c++ - 模板内的编辑列表不保存