【发布时间】:2021-05-29 19:01:54
【问题描述】:
我编写了自己的定点数值类,打算像float 或double 一样使用:
template<typename T, unsigned Precision> struct fixed {...}
T 必须是 int8_t、int16_t、int32_t 或 int64_t,它将使用 Precision 位作为小数部分。没有指数部分。我已经实现了必要的运算符、转换运算符等,一切都按预期工作。
现在我想将这个类与 boost qvm 一起使用并创建我的固定类的 3 维向量:
using fixed_vec3 = boost::qvm::vec<fixed<int32_t, 10>, 3>;
auto my_vec3 = fixed_vec3{1.25, 2.5, 3.75};
到目前为止,一切都很好。但是如果我尝试获取向量的大小,我会遇到一个小问题:
auto my_mag = mag(my_vec3);
显然会产生链接器错误,我缺少在命名空间 boost::qvm 中定义并由 boost::qvm 中的 mag(...) 方法使用的 sqrt 方法特化:
namespace boost::qvm {
...
template <class T> T sqrt( T );
...
template <> BOOST_QVM_INLINE_TRIVIAL float sqrt<float>( float x ) { return ::sqrtf(x); }
...
template <> BOOST_QVM_INLINE_TRIVIAL double sqrt<double>( double x ) { return ::sqrt(x); }
...
}
我有自己的 sqrt 实现:
template<typename T, unsigned Precision>
fixed<T, Precision> sqrt(fixed<T, Precision> val)
{
return ...;
}
如何为我的模板化 fixed 类创建 boost::qvm::sqrt 的专业化?以下内容已经非常适合fixed 的特定专业化:
namespace ::boost::qvm {
template<>
inline fixed<int32_t, 10>
sqrt<fixed<int32_t, 10>>(fixed<int32_t, 10> value)
{
return ...
}
}
注意:在boost::qvm中的mag方法内部,方法sqrt是这样调用的:
...
T const m2=a0*a0+a1*a1+a2*a2;
T const mag=sqrt<T>(m2);
return mag;
...
但是,我当然想为所有可能的fixed 模板创建一个模板版本,而不是为fixed<int32_t, 10> 分别创建一个模板版本。枚举它们。重载当然不起作用,因为使用一个参数显式引用了模板。在这种情况下这甚至可能吗?我该怎么做(当然不改变 boost 源代码)?
顺便说一句:我正在使用 Microsoft C++ 编译器 Visual Studio 2019,分别使用 C++ 20。 “最新的工作草案 c++”。
【问题讨论】:
-
它不能解决你的问题,但是 Boost 不应该提供那个显式的模板参数——而且它应该通过一个可以处理部分特化的类模板进行转发。