Re: [问题] 如何消除泛型降转的警告

楼主: poyenc (发箍)   2019-08-28 18:04:24
※ 引述《s4300026 (s4300026)》之铭言:
: 开发平台(Platform): (Ex: Win10, Linux, ...)
: win7
: 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
: vc2010
: 额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
: 问题(Question):
: 如题
: 喂入的资料(Input):
: T = Point, K = float
: T = PointF, K = double
: 预期的正确结果(Expected Output):
: 错误结果(Wrong Output):
: warning C4244
: 将 float 转 int 可能导致资料遗失
: 将 double 转 float 可能导致资料遗失
: 程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
: template <typename T, typename K>
: void func(T a, K b, T &c)
: {
: c.X = a.X * b;
: }
: 补充说明(Supplement):
: 原本以为 decltype 可以帮上忙, 但似乎不能这样写...
: c.X = (decltype c.X) (a.X * b);
: 正确写法
: c.X = (decltype (c.X)) (a.X * b);
: 看到 warning 很烦躁...
: 我知道T, K不能乱丢型态进去
: 因此我想要把泛型做成 class private
: 然后 public 指定的T K
: 感谢大大拨冗观看
在 C++98 里通常是请 Point 提供 X 的型别给你, 即在类别里提供
member types, 通常这样可以避免不必要的 implicit conversion,
更换实作容易, 且对 client side 程式码冲击较小
struct Point {
using XType = int;
XType X;
};
template <typename T, typename K>
void func(T a, K b, T &c)
{
c.X = static_cast<typename T::XType>(a.X * b);
}
因为这样对型别的 constraint 加大了, 在 C++11 里面虽然可以用
decltype 取得 X 的型别, 不过需要注意运算子的引数为何, 一般
建议使用 T::X 加上 std::decay 拿到不含 & 的型别
struct Point {
int X;
};
template <typename T, typename K>
void func(T a, K b, T &c)
{
using XType = typename std::decay<decltype(T::X)>::type;
c.X = static_cast<XType>(a.X * b);
}
不过因为这个模版实在太泛用了, 导致阿猫阿狗都有可能被编译器
丢进来尝试具现化. 建议帮它加上一些 constraints, 这里用的是
简化版的 detection idiom
范例: https://wandbox.org/permlink/OLxNtrWosKLv9NQI
作者: s4300026 (s4300026)   2019-08-28 22:13:00
那个 ... 我的 Point, PointF 是 Clr 的 WinForm 结构..所以没办法定义型别至于func(T a, K b, T &c) -> 的箭头有看过一两次但目前完全没搞动那个是做什么用的至于 template <typename...> using void_t = void;则是连看都没看过...
作者: loveme00835 (发箍)   2019-08-28 22:25:00
关键字: trailing return type, variadic template
作者: s4300026 (s4300026)   2019-08-28 22:25:00
不过还是谢谢你的回答
作者: s4300026 (s4300026)   2019-08-29 09:04:00

Links booklink

Contact Us: admin [ a t ] ucptt.com