c++:设置一个局部专门化等于另一个

C++: Set one partial specialization equal to another

本文关键字:专门化 局部 另一个 一个 设置 c++      更新时间:2023-10-16

我写了一个类模板,签名如下:

template<typename ... Args> struct MyClass {};
template<typename ... A, B> struct MyClass< std::tuple<A ...>, B> {};
对于这个场景,我有两个密切相关的问题,它们都涉及到部分专门化可以相互映射的方式。如果,尽管我或多或少彻底地搜索了,这些问题已经在这里得到了解决,我也很乐意提供这些帖子的链接。

问题1:在代码中,不要写

MyClass< std::tuple<>, B> myClass;

,我想创建相应的对象

MyClass<B> myClass;
我的第一个方法是使用继承,
template<typename B>
struct Myclass<B> : public MyClass<std:tuple<>, B>
{
    typedef MyClass<std:tuple<>, B> Base;
    using Base::Function1;
    using Base::Function2;
    // ...
}

但是,如果我看对了,那么我必须将基类函数带到派生类名称空间中。此外,从原则上考虑,这些类应该是"相同的",而不是通过类似继承的"is-an"关系相关联。

是否有其他方法可以做到这一点,例如使用模板混叠(using关键字)?例如as (but this does not work)

template<typename B> struct MyClass<B> = MyClass<std::tuple<>, B>;

任何其他可行的替代方案都是受欢迎的,它将在没有太多开销的情况下使一个部分专业化与另一个部分专业化相等。


问题2至少在我看来是密切相关的。一般来说,我宁愿完全避免写"tuple"。因此,在与上面相同的非工作方式中,但更普遍的是,我想写一些像

这样的东西
template<typename ... A, typename B> struct MyClass<B, A ... > = MyClass<std::tuple<A ...>, B>;

(我在专门化中交换了A ...B的顺序,因为至少Visual Studio希望将包扩展作为最后一个参数。)

任何帮助都是感激的,提前感谢。


EDIT:它似乎不能与模板别名一起工作,见这里。

您可以使用额外的间接级别,例如:

template<typename ... Args> struct MyClass_impl {};
template<typename ... Ts, typename T> struct MyClass_impl<std::tuple<Ts ...>, T> {};
namespace detail
{
    template<typename T, typename ... Ts>
    struct Helper
    {
        using type = MyClass_impl<std::tuple<Ts...>, T>;
    };
    template<typename ... Args, typename ... Ts>
    struct Helper<std::tuple<Args...>, Ts...>
    {
        using type = MyClass_impl<std::tuple<Args...>, Ts...>;
    };
}
template <typename ... Ts>
using MyClass = typename detail::Helper<Ts...>::type;

但是,如果我看对了,那么我必须将基类函数带到派生类名称空间中。

我不确定你在这里的意思,但是来自公共基类的名称已经可以在派生类作用域中访问。

是否有其他方法可以做到这一点,例如使用模板混叠(using关键字)?

MyClass是类模板,不能是别名模板

如果我对你的问题理解正确的话,我想你可能已经自己回答过了。

typedef MyClass<std:tuple<>, B> Base;

那么你可以直接写

Base myClass;

对于你的其他问题也是一样的。