我编写了一个带有以下签名的类模板:
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。欢迎其他替代方案。
答案 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;
同样适合你的其他问题。