【发布时间】:2021-11-08 13:26:10
【问题描述】:
我知道当一个基类只被前向声明时会发生这种类型的错误,但就我而言,据我所知它已经完全实现了:
我正在尝试使用文字和代数运算符创建一个只有在使用正确的单位时才能编译的单位系统。
我从一个基类 Units 开始,它只是 T 的一个包装器,并被所有其他单元继承。
然后我定义允许的代数运算符,它应该返回正确的单位。
我明白了
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
}
【问题讨论】:
-
using typename Units<T>::Units;->using Units<T>::Units;. -
@Jarod42 有了你推荐的修复和其他一些修复,我让它运行起来了:Demo on coliru
-
你用的是什么编译器?我得到了完全不同的错误。
-
@Jarod42 using typename Units
::Units 实际上没问题(stackoverflow.com/questions/25940365/…),解决它的是返回语句中的显式模板参数,如下面的答案所述。 -
把它放在一个接受的 SO 答案中 并且 让 gcc 接受它并不能让它好起来。 If the terminal name of the using-declarator is dependent ([temp.dep.type]), the using-declarator is considered to name a constructor if and only if the nested-name-specifier has a terminal name that is the same as the unqualified-id。所以
Units<T>::Units命名了一个构造函数,而不是一个类型,并且添加typename并不会神奇地让它变得如此。 Clang 拒绝此构造。
标签: c++ templates inheritance c++20