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?
类似的行为可能是早期的reported,可能是Clang错误:[错误23107]模板上的构造方法继承无法正常工作。
理查德·史密斯对此报告的评论:
C ++委员会已经讨论了这种情况,并不打算使用该语法是有效的。使用
using myBase::myBase;
来声明继承的构造函数。
因此,您应该写using Base::Base;
而不是using Base::A;
。修复之后,您的代码将使用Clang进行编译。
正如其他人所评论的那样,您的代码可以在最新的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;
};