[分享] 一个 variadic template 形式的问题

楼主: yoco315 (眠月)   2014-09-09 11:48:29
周末自干一个 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;
});
}
竟然过了 = =||
虽然不知道原因,其实标准我也没很熟,但总之会动就好
分享一下,以免以后有人撞到一样的问题
作者: azureblaze (AzureBlaze)   2014-09-09 12:11:00
http://ideone.com/UGsyKZ 看起来像是gcc的bug他觉得两边导出来的double是不同的东西
楼主: yoco315 (眠月)   2014-09-09 13:50:00
我是用 clang++-3.5 @@~ 可能两边都有这 bug?
作者: suhorng ( )   2014-09-09 14:11:00
不知道这样 deduction 怎么推的XD 难道是直接形式上match所以万一 variant 没有前面 typename T0 会可过?
作者: azureblaze (AzureBlaze)   2014-09-09 14:48:00
没T0会过
楼主: yoco315 (眠月)   2014-09-09 15:32:00
我这边的状况是,如果 variant 是 <T0, Rest...>那 << 也要是 <T0, Rest...> 的形式才会过,不然推导失败不办法直接写成 <Ts...> Q_Q
作者: jackace (inevitable......)   2014-09-09 15:39:00
为什么不写primary class然后有T0的作partial specializag++4.9.0会过
作者: suhorng ( )   2014-09-09 15:51:00
唔, 用 4.9.1 有过++

Links booklink

Contact Us: admin [ a t ] ucptt.com