※ 引述《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