[分享] 一個 variadic template 形式的問題

看板C_and_CPP (C/C++)作者 (眠月)時間11年前 (2014/09/09 11:48), 編輯推噓3(309)
留言12則, 4人參與, 最新討論串1/1
週末自幹一個 variant ( 類似 http://www.boost.org/doc/libs/1_56_0/doc/html/variant.html ) 我的 variant 宣告長這樣 template <typename T0, typename ... Rest> class variant { ... }; 在幫這個 class variant 加上 std::cout << 的支援的時候遇到一個小問題 template <typename ... Ts> std::ostream& operator<<(std::ostream& os, const variant<Ts...>& v) { return v.apply([&os](const auto& m) -> decltype(auto) { return os << m; }); } 然後使用他 variant<int, double> v{3}; std::cout << v << std::endl; // 編譯失敗,找不到對應的 << candidate 當中有我寫的那個 operator<< 版本,但 Ts... 被推導成 <> 也就是一個 type argument 都沒有推導成功 神奇的是我改成 template <typename T0, typename T1> std::ostream& operator<<(std::ostream& os, const variant<T0, T1>& v) { return v.apply([&os](const auto& m) -> decltype(auto) { return os << m; }); } 就成功了,百思不得其解。 可是這種寫法,只能用在固定個數的 type arguments。 後來想一想,該不會是 template args 的形式上也要對應吧 = =|| 於是改成像 variant<T0, Rest...> 的形式試試看 template <typename T0, typename ... Rest> std::ostream& operator<<(std::ostream& os, const variant<T0, Rest...>& v) { return v.apply([&os](const auto& m) -> decltype(auto) { return os << m; }); } 竟然過了 = =|| 雖然不知道原因,其實標準我也沒很熟,但總之會動就好 分享一下,以免以後有人撞到一樣的問題 -- To iterate is human, to recurse, divine. 遞迴只應天上有, 凡人該當用迴圈.   L. Peter Deutsch -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.251.36.252 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1410234512.A.38C.html

09/09 12:11, , 1F
http://ideone.com/UGsyKZ 看起來像是gcc的bug
09/09 12:11, 1F

09/09 12:13, , 2F
他覺得兩邊導出來的double是不同的東西
09/09 12:13, 2F

09/09 13:50, , 3F
我是用 clang++-3.5 @@~ 可能兩邊都有這 bug?
09/09 13:50, 3F

09/09 14:11, , 4F
不知道這樣 deduction 怎麼推的XD 難道是直接形式上match
09/09 14:11, 4F

09/09 14:11, , 5F
所以萬一 variant 沒有前面 typename T0 會可過?
09/09 14:11, 5F

09/09 14:48, , 6F
沒T0會過
09/09 14:48, 6F

09/09 15:32, , 7F
我這邊的狀況是,如果 variant 是 <T0, Rest...>
09/09 15:32, 7F

09/09 15:32, , 8F
那 << 也要是 <T0, Rest...> 的形式才會過,不然推導失敗
09/09 15:32, 8F

09/09 15:33, , 9F
不辦法直接寫成 <Ts...> Q_Q
09/09 15:33, 9F

09/09 15:39, , 10F
為什麼不寫primary class然後有T0的作partial specializa
09/09 15:39, 10F

09/09 15:48, , 11F
g++4.9.0會過
09/09 15:48, 11F

09/09 15:51, , 12F
唔, 用 4.9.1 有過++
09/09 15:51, 12F
文章代碼(AID): #1K3dYGEC (C_and_CPP)
文章代碼(AID): #1K3dYGEC (C_and_CPP)