[type_traits] is_empty fails on final classes.
Hi. It seems boost::is_empty uses Empty Base Optimisation to detect whether a class type is stateless or not. This predictably fails on final types, as they cannot be inherited from: #include <iostream> #include <boost/type_traits.hpp> class Test final {}; int main() { std::cout << boost::is_empty<Test>::value; return 0; } Fails on gcc 4.8.1 with In file included from /usr/local/include/boost/type_traits.hpp:54:0, from main.cpp:2: /usr/local/include/boost/type_traits/is_empty.hpp: In instantiation of 'struct boost::detail::empty_helper_t1<Test>': /usr/local/include/boost/type_traits/is_empty.hpp:79:5: required from 'const bool boost::detail::empty_helper<Test, true>::value' /usr/local/include/boost/type_traits/is_empty.hpp:88:5: required from 'const bool boost::detail::is_empty_impl<Test>::value' /usr/local/include/boost/type_traits/is_empty.hpp:220:1: required from 'struct boost::is_empty<Test>' main.cpp:7:39: required from here /usr/local/include/boost/type_traits/is_empty.hpp:52:8: error: cannot derive from 'final' base 'Test' in derived type 'boost::detail::empty_helper_t1<Test>' struct empty_helper_t1 : public T ^ Yet std::is_empty works just fine (al least in gcc), and appears to be implemented via an intrinsic: template<typename _Tp> struct is_empty : public integral_constant<bool, __is_empty(_Tp)> {}; Now, is it at all possible to implement conforming is_empty without resorting to compiler magic that are intrinsics?
On 22 December 2013 13:53, yuri kilochek wrote:
Now, is it at all possible to implement conforming is_empty without resorting to compiler magic that are intrinsics?
No, I don't think it's possible. On the plus side, any compiler that supports the 'final' keyword must provide some sort of intrinsic for its own std::lib, so Boost can use the relevant intrinsic for each such compiler.
22.12.2013 20:38, Jonathan Wakely пишет:
Now, is it at all possible to implement conforming is_empty without resorting to compiler magic that are intrinsics?
No, I don't think it's possible. On the plus side, any compiler that supports the 'final' keyword must provide some sort of intrinsic for its own std::lib, so Boost can use the relevant intrinsic for each such compiler.
Why not to use std::is_empty for all of them? -- Best regards, Sergey Cheban
participants (3)
-
Jonathan Wakely
-
Sergey Cheban
-
yuri kilochek