【问题标题】:Unable to import of typedefs from template base class无法从模板基类导入 typedef
【发布时间】:2018-11-06 15:34:51
【问题描述】:

这个问题不是重复的而是跟进 Propagating 'typedef' from based to derived class for 'template'

作为继承typedef的解决方案,建议使用using将它们导入派生类,而简单的using typename Base::typedefed_type应该就足够了。

以下代码大部分取自Roman Kruglov's answer

#include <vector>
template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
public:
    using typename A::Vec_t;
    // .........

private:
    Vec_t v;
};

int main()
{
B<int> bb;
}

但是它无法编译,因为编译器非常需要 A 的模板参数。

英特尔编译器错误信息:

    1>C:\Work\EDPS\test_eigen\test_eigen.cpp(27): error : argument list for class template "A" is missing
1>      using typename A::Vec_t;
1>                     ^
1>          detected during instantiation of class "B<T> [with T=int]" at line 34
1>
1>C:\Work\EDPS\test_eigen\test_eigen.cpp(31): error : identifier "Vec_t" is undefined
1>      Vec_t v;
1>      ^
1>          detected during instantiation of class "B<T> [with T=int]" at line 34
1>

MVC 错误信息:

 c:\work\edps\test_eigen\test_eigen.cpp(27): error C2955: 'A': use of class template requires template argument list
1>c:\work\edps\test_eigen\test_eigen.cpp(17): note: see declaration of 'A'
1>c:\work\edps\test_eigen\test_eigen.cpp(32): note: see reference to class template instantiation 'B<T>' being compiled
1>c:\work\edps\test_eigen\test_eigen.cpp(27): error C3210: 'A': a member using-declaration can only be applied to a base class member
1>c:\work\edps\test_eigen\test_eigen.cpp(32): warning C4624: 'B<int>': destructor was implicitly defined as deleted

那怎么了?我错过了什么吗?还是那里的 cmets 和答案错了??

【问题讨论】:

  • using typename A&lt;T&gt;::Vec_t;
  • 编译器错误非常简单:您使用的A 没有在需要的地方提供参数列表。
  • 我认为这不是一个错字。错字是作者知道但打错的东西。这里我想作者没有意识到 typename A 和 typename A 是不同的。
  • 有人努力阅读链接的线程吗?出现了整个问题,因为有人建议 using typename A::Vec_t; 就足够了。代码也是从那里复制过来的。
  • @AndreyPro 答案是错误的。我留下了comment

标签: c++ templates inheritance typedef using


【解决方案1】:

我认为混淆源于A 用作基类的方式。如果类模板派生自带有模板参数的类模板,则必须完全限定基类名称。但是,如果一个类派生自类模板特化,则可以使用基类名称而不使用模板参数列表。

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

template<typename T>
struct B : A<T> {
    using typename A<T>::t; // Full qualification needed -> mandatory argument list
};

struct C : A<int> {
    using typename A::t; // Injected class name -> optional argument list
};

Live on Coliru

另外,请注意t 直接在C 中可用,无需任何 using 声明或 typedef。我可能仍然有用,例如如果C 私下继承自A&lt;int&gt;,但您希望tC 中公开可用(在示例中,C 默认公开继承,因为它是@ 987654331@).

【讨论】:

    【解决方案2】:

    修改成这样就行了

    template<typename T>
    class B : public A<T>
    {
    public:
        using typename A<T>::Vec_t;
        // .........
    
    };
    

    在 C++ 中,如果 A 是模板,则独立的 A 不是“完整”类型。您需要指定模板参数。这就是A&lt;T&gt; 解决它的原因。

    【讨论】:

    • 对低质量问题的答案投反对票。相反,它应该是 VTC 的评论,作为“印刷错误”
    • @AndreyPro 我很明白问了什么,谢谢。
    • 顺便说一句,这不是关于typename A,而是关于A
    猜你喜欢
    • 2010-12-11
    • 2012-11-04
    • 2016-02-02
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    相关资源
    最近更新 更多