为什么不能使用 typedef 类型来声明其父 class' 构造函数?
Why can't a typedef type be used to declare its parent class' ctors?
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 类型声明其父 class 构造函数?
早期的类似行为 reported 作为可能的 Clang 错误:[错误 23107] 模板上的构造函数继承无法正常工作。
Richard Smith 对此报告的评论:
The C++ committee have discussed this case and did not intend for that syntax
to be valid. Use using myBase::myBase;
instead to declare an inheriting constructor.
所以,你应该写using Base::Base;
而不是using Base::A;
。修复后,您的代码将使用 Clang 进行编译。
正如其他人评论的那样,您的代码在最新的 GCC 和 MSVC 上编译没有问题。
您的问题似乎发生在 Clang 上。
该标准与析构函数的命名问题类似 (source):
In a qualified-id of the form:
[...] type-name::~type-name
the second type-name is looked up in the same scope as the first.
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
class 设为非模板,它也适用于 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;
};
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 类型声明其父 class 构造函数?
早期的类似行为 reported 作为可能的 Clang 错误:[错误 23107] 模板上的构造函数继承无法正常工作。
Richard Smith 对此报告的评论:
The C++ committee have discussed this case and did not intend for that syntax to be valid. Use
using myBase::myBase;
instead to declare an inheriting constructor.
所以,你应该写using Base::Base;
而不是using Base::A;
。修复后,您的代码将使用 Clang 进行编译。
正如其他人评论的那样,您的代码在最新的 GCC 和 MSVC 上编译没有问题。
您的问题似乎发生在 Clang 上。
该标准与析构函数的命名问题类似 (source):
In a qualified-id of the form:
[...] type-name::~type-name
the second type-name is looked up in the same scope as the first.
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
class 设为非模板,它也适用于 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;
};