当 class 已完全定义时,为什么我会得到 "invalid use of incomplete type"?

Why do I get "invalid use of incomplete type", when the class is fully defined?

我知道当基数 class 仅向前声明时会发生这种类型的错误,但就我而言,据我所知它已完全实现:

我正在尝试创建一个单位系统,该系统只有在使用正确的单位时才会编译,使用文字和代数运算符。

我从基础 class 单元开始,它只是 T 的包装器,并被所有其他单元继承。

然后我定义允许的代数运算符,它应该 return 正确的单位。

我明白了

error: invalid use of incomplete type ‘class Units<T>’
[build]   107 |     return Mps{static_cast<T>(rhs) / static_cast<T>(lhs)};

对于此代码:

template<typename T>
class Units
{
protected:
    T val;
public:
    constexpr explicit Units(T val) : val(val) { }
    constexpr explicit operator T&() { return val; }
    constexpr explicit operator T() const { return val; }
    constexpr auto operator<=>(const Units<T> rhs) {
        return val <=> rhs.val; 
    }
    constexpr bool operator==(const Units<T> rhs) const { return val == rhs.val; }

};


template<typename T>
class Meters : public Units<T>
{
    using typename Units<T>::Units;
};

template<typename T>
class Seconds : public Units<T>
{
    using typename Units<T>::Units;
};

template<typename T>
class Mps : public Units<T>
{
    using typename Units<T>::Units; 
};


constexpr Meters<long double> operator "" _km(long double km) {
    return Meters<long double>{1000 * km};
}


constexpr Seconds<long double> operator "" _s(long double s) {
    return Seconds<long double>{s};
}


constexpr Mps<long double> operator "" _mps(long double s) {
    return Mps<long double>{s};
}


template<typename T>
constexpr Mps<T> operator / (const Meters<T> &&rhs, const Seconds<T> &&lhs) {
    return Mps{static_cast<T>(rhs) / static_cast<T>(lhs)};
}


int main() {
    return 1_km / 2_s == 500_mps
}

看起来编译器很困惑,警告具有误导性。提供缺少的模板参数以修复它:

return Mps<T>{static_cast<T>(rhs) / static_cast<T>(lhs)};
          ^^^

如果您希望避免明确指定参数,您可以(可能)定义一个演绎指南。


其他问题:

  • 缺少分号。
  • 你的运算符是针对浮点数的,但你在1_km中使用整数;那是行不通的。要么使用浮点文字,要么为整数添加重载。
  • using typename Units<T>::Units; 是错误的。丢掉 typename.