如何使用当前类模板作为其他模板的模板参数
How to use the current class template as template parameter for another template?
我使用递归继承的递归模板类
我试图定义一种获得第n个基数的抽象方法(比如基数0是当前类,基数1是其基数,基数2是其基数等)
(在这个例子中,模板参数是size_t
,但相同的原理适用于typename
或class
。)
我可以使用部分专用的helper结构来完成这项工作。但我想让它独立于模板(而不是在我有递归模板的时候制作一个辅助结构),如下所示:
namespace helper
{
template<template<size_t...> typename templ, size_t pos, size_t s0, size_t... rest>
struct getter
{
typedef typename getter<templ, pos - 1, rest...>::type type;
type &operator()(templ<s0, rest...> &s)
{
getter<templ, pos - 1, rest...> getter;
return getter(static_cast<templ<rest...>&> (s));
}
};
template<template<size_t...> typename templ, size_t s0, size_t... rest>
struct getter<templ, 0, s0, rest...>
{
typedef templ<s0, rest...> type;
type &operator()(templ<s0, rest...> &s)
{
return s;
}
};
}
现在,在我的模板类中,我想使用这个助手来生成一个函数get<size_t n>()
,它向我返回对第n个基的引用(代码在get
声明时编译失败):
template<size_t...>
struct record {};
template<size_t n, size_t... rest>
struct record<n, rest...> : record<rest...>, value<n>
{
template<size_t pos>
typename helper::getter<record, pos, n, rest...>::type::value_type &get()
{
helper::getter<record, pos, n, rest...> getter;
return static_cast<typename helper::getter<record, pos, n, rest...>::type::value_type&>(getter(*this));
}
};
这失败了,因为在record
模板中,record
是最终类,而不是模板。我想使用类似"当前模板"的东西,而不是"当前实例化的类"。
我找到的唯一解决方法(适用于Visual Studio 2015)是使用全局别名来复制模板:
template<size_t...s>
using g_record = record<s...>;
然后修改get声明以调用全局别名(指向相同类型):
...
template<size_t pos>
typename helper::getter<g_record, pos, n, rest...>::type::value_type &get()
{
helper::getter<g_record, pos, n, rest...> getter;
return static_cast<typename helper::getter<g_record, pos, n, rest...>::type::value_type&>(getter(*this));
}
...
有没有更直接或"正确"的方法来做到这一点?
看起来我的挖掘有点仓促。
显然,使用模板的完全限定名称是有效的(在我的示例中是::record
):
template<size_t pos>
typename helper::getter<::record, pos, n, rest...>::type::value_type &get()
{
helper::getter<::record, pos, n, rest...> getter;
return static_cast<typename helper::getter<::record, pos, n, rest...>::type::value_type&>(getter(*this));
}
不需要使用任何技巧让编译器意识到您使用的是record
作为模板名称,而不是引用当前实例化的类型名称。参见【temp.local】/1,强调矿:
与普通(非模板)类一样,类模板有一个注入的类名(第9条)。注入的类名可以用作模板名或类型名。当它与模板参数列表一起使用时,作为模板template参数的模板参数,或者作为友类模板声明的explated类型说明符中的最终标识符,引用类模板本身。否则,它等效于
<>
中包含的类模板的模板名称,后跟的模板参数。
您发布的解决方法是正确的,但不应该需要;这是编译器中的一个错误。
- C++ 默认参数使用其他参数
- lambda 作为接受其他参数的参数的初始化顺序
- 了解'this'或其他参数是否为右值
- 递归回文检查,不使用向量、大小或其他参数
- 模板模板参数用作其他参数的默认值
- 可以移动构造函数以除班级本身以外的其他参数
- 在传递其他参数时在 C++ 中重载运算符
- 具有可变参数模板参数的部分专用化,后跟其他参数
- 在参数包中获取函数指针的返回类型,并将其保存为与其他参数连接的元组
- 委托构造函数和默认参数,具体取决于其他参数
- 在boost :: static_visitor中operator()中的其他参数
- 带有映射参数的函数需要其他参数
- 是否有一个WinAPI可以从带有可选空格和其他参数的命令行获取文件名
- 后面跟有其他参数的函数参数包的模板参数推导
- 将字符串(或任何其他参数)传递到QWidget构造函数
- 使用其他参数的默认参数
- 如何设置依赖于其他参数的参数默认值
- C++获取具有其他参数的构造函数的初始值设定项列表
- C++函数模板,函数作为参数,取决于其他参数
- 使用 boost::bind 但允许传递任何其他参数