【问题标题】:Inheritance of user defined types in templated definitions模板化定义中用户定义类型的继承
【发布时间】:2022-01-03 06:25:05
【问题描述】:

我的理解是,在 C++ 中,用户定义的类型是被继承的,而且在某种程度上确实如此。

这是我正在尝试做的,但这不能编译:

template <typename T>
struct A{
    using type = T;
};

template <typename T>
struct B: A<T>{
    using type2 = type;
};

但是,如果我有 B 扩展 A 的非模板参数,它可以工作:

template <typename T>
struct A{
    using type = T;
};

template <typename T>
struct B: A<int>{
    using type2 = type;
};

确实,我发现了一种解决方法(但对于我正在尝试做的事情并没有真正帮助我的是范围 type 但这会破坏继承点:

template <typename T>
struct A{
    using type = T;
};

template <typename T>
struct B{
    using type2 = A<T>::type;
};

是否有适当的方法来实现我想要的行为(在更一般的情况下,这显然是一个玩具示例)以及它的语义是什么?

编辑:这是我希望代码的样子,可以解决缺乏继承的问题,但我想了解限制是什么

template <typename t>
struct instruction{
    public:
    using input = t::first;
    using mem = t::second;

    using newmem = mem;
    using newinput = input;

    using result = pair<newinput, newmem>;
};



template <typename t>
struct right_code: public instruction<t>{
    using newmem = buffer<cons<mem::list2::head, mem::list1>, (std::is_same<mem::list2::tail , nil> ? cons<zero, nil>
                                                                                                    : mem::list2::tail)>;
};

template <typename t>
using right = right_code<t>::result;



template <typename t>
struct left_code:instruction<t>{
    using newmem = (std::is_same<mem::list1::tail, nil ? mem
                                                       : buffer<mem::list1::tail, cons<mem::list1::head, mem::list2>);
};

template <typename t>
using left = left_code<t>::result;

【问题讨论】:

  • 你能举一个例子来说明为什么using type2 = A&lt;T&gt;::type; 不适合你吗?在这种涉及依赖于模板参数的基类的情况下,需要某种明确的限定;问题是你可以接受什么样的结构。
  • 查看this 了解可能的重复。
  • 我认为问题是为什么如果B 是A&lt;T&gt;,B::type 不存在,就像A 有int foo() const;,B 会有它也是。

标签: c++ templates template-meta-programming


【解决方案1】:

使用typename A&lt;T&gt;::type。

template <typename T>
struct A {
    using type = T;
};

template <typename T>
struct B : A<T> {
    using type2 = typename A<T>::type;
};

using type2 = type 不适用于 struct B : A&lt;T&gt;,因为 type 是一个非依赖名称,因此名称查找不会受到实例化时可见声明的影响,请参阅 https://en.cppreference.com/w/cpp/language/unqualified_lookup

例如,

template <typename T>
struct A {
    using type = T;
};

template <>
struct A<int> : public C<int> {
    // it doesn't need to have `type`
};

A&lt;T&gt; 甚至不需要type 来进行某些专业化。我们看到来自A&lt;T&gt; 的声明在我们实例化它之前是不确定的。

通过使用typename A&lt;T&gt;::type,我们在 T 上创建了一个依赖名称,这将名称查找“推迟”到实例化点。

相比之下,对于struct B : A&lt;int&gt;,using type2 = type 工作得很好,因为A&lt;int&gt; 是显式实例化的,所以A&lt;int&gt;::type 在模板定义上下文中是可见的。

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多