Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将当前类模板用作其他模板的模板参数?_C++_Templates_Recursion_Metaprogramming - Fatal编程技术网

C++ 如何将当前类模板用作其他模板的模板参数?

C++ 如何将当前类模板用作其他模板的模板参数?,c++,templates,recursion,metaprogramming,C++,Templates,Recursion,Metaprogramming,我正在使用递归继承的递归模板类。 我试图定义一种获取第n个基的抽象方法(比如,基0是当前类,基1是它的基,基2是基的基等等) (在本例中,模板参数为size\u t,但相同的原则适用于typename或class) 我可以使用部分专用的helper结构来完成这项工作。但我想使其独立于模板(并且在使用递归模板时不生成帮助器结构),如下所示: namespace helper { template<template<size_t...> typename templ, si

我正在使用递归继承的递归模板类。
我试图定义一种获取第n个基的抽象方法(比如,基0是当前类,基1是它的基,基2是基的基等等)

(在本例中,模板参数为
size\u 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;
        }
    };
}
这会失败,因为在
记录
模板中,
记录
是最终类,而不是模板。我想使用“当前模板”而不是“当前实例化的类”

我发现的唯一解决方法(在Visual Studio 2015下工作)是使用全局别名复制模板:

template<size_t...s>
using g_record = record<s...>;
模板
使用g_记录=记录;
然后修改get声明以调用全局别名(指向同一类型):

。。。
模板
typename助手::getter::type::value\u type&get()
{
helper::getter-getter;
返回静态_cast(getter(*this));
}
...

有没有更直接或“正确”的方法来做这件事?

看起来我在挖掘时有点匆忙

显然,使用模板的完全限定名是有效的(在我的示例中,它是
::record
):

模板
typename助手::getter::type::value\u type&get()
{
helper::getter-getter;
返回静态_cast(getter(*this));
}

看来我挖掘的时候有点匆忙

显然,使用模板的完全限定名是有效的(在我的示例中,它是
::record
):

模板
typename助手::getter::type::value\u type&get()
{
helper::getter-getter;
返回静态_cast(getter(*this));
}

不必使用任何技巧让编译器意识到您使用的是
记录
作为模板名,而不是引用当前实例化的类型名。参见[temp.local]/1,重点:

像普通(非模板)类一样,类模板有一个注入的类名(第9条)。注入的类名可以用作模板名或类型名。当它与模板参数列表一起使用时, 作为模板参数的模板参数,或作为友元类模板声明的详细类型说明符中的最终标识符,它引用类模板本身。否则,它相当于模板名称后跟
中包含的类模板的模板参数


您发布的解决方案是正确的,但不应该是必需的;这是编译器中的一个错误。

不必使用任何技巧让编译器意识到您正在使用
记录
作为模板名,而不是引用当前实例化的类型名。参见[temp.local]/1,重点:

像普通(非模板)类一样,类模板有一个注入的类名(第9条)。注入的类名可以用作模板名或类型名。当它与模板参数列表一起使用时, 作为模板参数的模板参数,或作为友元类模板声明的详细类型说明符中的最终标识符,它引用类模板本身。否则,它相当于模板名称后跟
中包含的类模板的模板参数

您发布的解决方案是正确的,但不应该是必需的;这是编译器中的一个bug

template<size_t...s>
using g_record = record<s...>;
...
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));
}
...
    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));
    }