C ++:将一个部分特化设置为另一个

时间:2014-08-08 13:21:09

标签: c++ templates c++11 variadic-templates partial-specialization

我编写了一个带有以下签名的类模板:

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;
    // ...
}

但是,如果我看对了,那么我必须将基类函数带到derived-class命名空间。此外,在原则上更多地思考,这些类应该是“相同的”,并且通过类似继承的“is-an”关系不相关。

有没有其他方法可以做到这一点,例如使用模板别名(using关键字)?例如。 as(但这不起作用)

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

欢迎任何其他工作替代方案,它应设置一个部分专业化等于另一个,而没有太多开销。


问题2 至少与我能看到的密切相关。一般来说,我宁愿避免写“元组”。所以以与上面相同的非工作方式,但更一般地说,我想写类似

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

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

提前感谢任何帮助。


编辑:它似乎不适用于模板别名,请参阅here。欢迎其他替代方案。

3 个答案:

答案 0 :(得分:4)

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

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;

答案 1 :(得分:1)

  

但是,如果我看对了,那么我必须将基类函数带到derived-class命名空间。

我不确定你的意思,但公共基类中的名称已经可以在派生类范围内访问。

  

还有其他方法吗,例如使用模板别名(using关键字)?

没有。 MyClass是一个类模板,它也不能是别名模板。

答案 2 :(得分:0)

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

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

然后你就写了

Base myClass;

同样适合你的其他问题。