为什么不能使用typedef类型声明其父类的ctor?

时间:2020-05-05 04:05:37

标签: c++ inheritance typedef using-directives using-declaration

template<typename>
struct A
{
    int n;

    A(bool)
    {}
};

template<typename>
struct B
{
    struct C : A<B>
    {
        using Base = A<B>;

        using A<B>::A; // ok
        using Base::n; // ok

        // error: dependent using declaration resolved to type without 'typename'
        using Base::A;
    };

    C get() const
    {
        return C(true);
    }
};

int main()
{
    auto b = B<int>();
    b.get();
}

该错误在代码中进行了描述。

为什么不能使用typedef类型声明其父类的ctor?

2 个答案:

答案 0 :(得分:4)

类似的行为在reported之前是可能的Clang错误: [错误23107]模板上的构造方法继承无法正常工作

理查德·史密斯对此报告的评论:

C ++委员会已经讨论了这种情况,并不打算使用该语法 是有效的。使用using myBase::myBase;来声明继承的构造函数。

因此,您应该写using Base::Base;而不是using Base::A;。修复之后,您的代码将使用Clang编译。

答案 1 :(得分:1)

正如其他人所评论的那样,您的代码可以在最新的GCC和MSVC上编译而不会出现问题。

您的问题似乎发生在Clang上。

该标准与析构函数(source)的命名问题类似:

采用以下形式的限定ID:

[...]类型名称::〜类型名称

在与第一个相同的作用域中查找第二个类型名称。

struct C {
  typedef int I;
};
typedef int I1, I2;
extern int* p;
extern int* q;
p->C::I::~I();      // I is looked up in the scope of C
q->I1::~I2();       // I2 is looked up in the scope of the postfix-expression

struct A {
  ~A();
};
typedef A AB;
int main() {
  AB* p;
  p->AB::~AB();     // explicitly calls the destructor for A
}

但是我找不到与构造函数有关的任何明确信息。我以为行为应该是相同的,但只有经验丰富的人才能确认。

有趣的是,如果您将A类设为模板,那么它也适用于Clang:

struct A
{
    A(bool) {}
};

template<typename>
struct B
{
    struct C : A
    {
        using Base = A;
        using Base::A;
    };
//...

那么也许这是Clang的错误?

您可以做的一件事是使用Base的构造函数:Base::Base

struct C : A<B>
{
    using Base = A<B>;
    using Base::Base;
};
相关问题