Boost logo

Boost :

Subject: [boost] [type_traits] is_empty fails on final classes.
From: yuri kilochek (yuri.kilochek_at_[hidden])
Date: 2013-12-22 08:53:11


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?


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk