模板化派生类隐藏基类成员?

时间:2021-06-22 21:03:58

标签: c++ inheritance class-template

我有一个从类模板继承的类。当我将派生类更改为模板时,编译器会抱怨基类数据成员未定义。

诚然,我正在以一种可能不合法的方式滥用参考资料。但是我在两个版本中都这样做,所以我想知道为什么编译器在一个版本中发现问题而不在另一个版本中。起初我认为这是一个编译器错误,但我使用 MSVC 和 Clang 得到了相同的结果。

// DISCLAIMER:  ABSURD EXPERIMENTAL CODE
#include <array>
#include <concepts>
#include <utility>

template <std::size_t N, std::floating_point T>
struct QNT {
    template <std::convertible_to<T>... Scalar>
    QNT(Scalar... values) : m{static_cast<T>(values)...} {
        static_assert(sizeof...(values) == N);
    }
    std::array<T, N> m;
};

#if CORRECT
using T = float;
#else
template <std::floating_point T>
#endif
struct Q2T : public QNT<2, T> {
    template <std::convertible_to<T> Tx, std::convertible_to<T> Ty>
    Q2T(Tx xx, Ty yy) : QNT<2, T>(xx, yy), x(m[0]), y(m[1]) {}

    T &x;
    T &y;
};

Compiler Explorer

如果你用 clang -std=c++20 -DCORRECT=1 编译,上面的代码会编译干净。 (它甚至可以做我希望它可以做的事情!)

如果将 CORRECT 更改为 0,则 T 从类型别名 T (using T = float;) 更改为派生类中的模板参数.在这种情况下,基类成员似乎不再可以从派生类访问。

<块引用>

<source>:21:40: error: use of undeclared identifier 'm' <source>:21:49: error: use of undeclared identifier 'm'

这些位置指的是 x 构造函数中 yQ2T 的初始值设定项。有些人在无法从基类构造函数访问派生类的成员时会感到困惑,但情况正好相反。基类成员 m 应在编译器声明未声明时完全初始化。

在失败的情况下,我是否实际实例化 Q2T 的对象没有区别。

0 个答案:

没有答案
相关问题