我希望有一个表示具有某种维度单位的类。它应该能够表示1.5平方米这样的数值。支持与某些类型进行标量乘法计算,并且无单位的数值应该与基础类型完全相同。这是我的解决方案:
#include <type_traits>
template<typename T, int Dim>
class Unit {
public:
explicit Unit(T t): _value(t) {}
template<int D = Dim, typename std::enable_if_t<D==0, int> = 0>
operator T() { static_assert(Dim==0, ""); return _value; } //static_assert not necessary, but gives error if template is removed
T _value;
};
template<typename S, typename T, int Dim>
auto operator*(S s, Unit<T,Dim> unit)
{
return Unit<T, Dim>(s * unit._value);
}
auto main() -> int
{
auto i = double{0};
//Scalar test
auto scalar = int{0};
auto x = Unit<double,1>(i);
auto test = scalar * x;
//Conversion test
auto y = Unit<double,0>(i);
return y + i;
}
这在clang中完美运行 (https://godbolt.org/z/8Pev7W6Y1)。然而,由于GCC存在模板转换操作符的错误 (Conversion operator: gcc vs clang), 所以在GCC中不起作用。
无法删除SFINAE结构,因为它(正确地)遇到了
static_assert
。你有没有关于等效代码的想法?该代码应该在C++17下使用两个编译器都可以工作。
operator T() requires (Dim == 0)
可以完成这项工作演示。 - Jarod42static_cast<double>(Unit<double,2>(0))
如果没有SFINAE(和static_assert
),将会编译错误。 - Jarod42operator*
之前尝试转换运算符,然后遇到static_assert
。我正在尝试修复这个示例。 - Henk