使类模板化会强制在继承构造函数中重复基类模板参数

Making class templated forces repeating base class template params in inheriting constructor

本文关键字:构造函数 基类 参数 继承      更新时间:2023-10-16

我最近将一个类从模板化改为不模板化,并发现在编写using声明以从模板化基类继承构造函数时,我不能再省略模板参数。只要我的类没有模板化,我就可以省略参数,只要是,我就不能。在下面的可编译代码段中,bar表示前面的类,buzz表示后面的类。我测试了GCC 5.2和Clang 3.7,它们有相同的行为。这是编译器错误还是标准错误?

#include <iostream>
template<class A, class B>
struct foo {
    foo(int x) {
        std::cout << x << std::endl;
    }
};
struct bar : foo<bar, short> {
    using foo::foo; // this appears legal
    // using foo<bar, short>::foo; // this works too, thought I would need it
};
template<class X>
struct buzz : foo<buzz<X>, short> {
     //using foo::foo; // no longer legal for some reason
    using foo<buzz<X>, short>::foo; // now do actually need this
};
int main() {
    bar x(3);
    buzz<float> y(5);
    return 0;
}

这是标准配置。

N4140 [temp.dep]/3:在类或类模板的定义中,如果基类依赖于模板参数,则基类在类模板的定义点进行非限定名称查找时,也不会检查作用域或者在类模板或成员的实例化期间。

对于buzz,基类依赖于模板参数,因此foo非限定查找不会检查其范围。这就是为什么您需要合格的查找。