18

Hallo,

is there some easy way in C++ to tell (in compile-time) if a class/struct has no data members?

E.g. struct T{};

My first thought was to compare sizeof(T)==0, but this always seems to be at least 1.

The obvious answer would be to just look at the code, but I would like to switch on this.

Johan Kotlinski
  • 24,287
  • 9
  • 75
  • 101

4 Answers4

17

Since C++11, you can use standard std::is_empty trait: https://en.cppreference.com/w/cpp/types/is_empty

If you are on paleo-compiler diet, there is a trick: you can derive from this class in another empty and check whether sizeof(OtherClass) == 1. Boost does this in its is_empty type trait.

Untested:

template <typename T>
struct is_empty {
    struct helper_ : T { int x; };
    static bool const VALUE = sizeof(helper_) == sizeof(int);
};

However, this relies on the empty base class optimization (but all modern compilers do this).

SergeyA
  • 59,974
  • 5
  • 72
  • 130
Konrad Rudolph
  • 506,650
  • 124
  • 909
  • 1,183
  • 2
    Will not work. As CashCow says this will not work for classes with virtual function. – UmmaGumma Jan 28 '11 at 14:06
  • 5
    @Ashot: That should not be "will not work" so much as "will not work given some definitions of empty". – GManNickG Jan 28 '11 at 14:12
  • @Ashot Martirosyan ... but the solution can be modified by deriving from some base helper class with dummy virtual function as welll as from the class being tested – user396672 Jan 28 '11 at 14:15
  • @GMan question is "has no data members". So answer is not clear. Your one are more clear IMHO :) – UmmaGumma Jan 28 '11 at 14:16
  • 1
    Ok, I should have made this clear: **don’t** use this metafunction, it’s for illustration purpose only. Use the Boost implementation, it’s much more robust and sophisticated! – Konrad Rudolph Jan 28 '11 at 14:16
  • 1
    This does work in the sense that it returns true for each empty class. However, if the result is false, the struct may or may not be empty, so "not `is_empty`" does not mean "is not empty". – Philipp Jan 28 '11 at 14:31
  • 1
    To @Konrad Rudolph. @user396672 is right, you can check is_polymorphic()&& sizeof(T)==sizeof(some_polymorphic_class). This will work for polymorphic classes on most compilers. It will not work only for classes with multiple inheritance (maybe also for classes with virtual bases). – UmmaGumma Jan 28 '11 at 14:46
12

If your compiler supports this aspect of C++0x, you can use std::is_empty from <type_traits>.

It's specification is:

T is a class type, but not a union type, with no non-static data members other than bit-fields of length 0, no virtual member functions, no virtual base classes, and no base class B for which is_empty<B>::value is false.

I don't think there's a standard way to find if a class is empty with regards to polymorphism.

GManNickG
  • 478,574
  • 51
  • 478
  • 539
  • how I already commented in Konrad Rudolph answer, it is possible to check if class is empty when it is polymorphic. You need to check `is_polymorphic()&& sizeof(T)==sizeof(some_polymorphic_class)`. This will work for polymorphic classes on most compilers. It will not work only for classes with multiple inheritance . – UmmaGumma Jan 28 '11 at 15:08
  • 4
    @Ashot: "on most compilers" I usually try not to think in terms of compilers. :) – GManNickG Jan 28 '11 at 15:14
3

Stepping on Konrad's answer, this handles classes with or without virtual functions.

template <typename T>
struct is_empty {
    struct empty_ { virtual ~empty_(); };
    struct helper_ : T { virtual ~helper_(); };
    static bool const EMPTY = sizeof(helper_) == sizeof(empty_);
};
Nick Dandoulakis
  • 41,532
  • 15
  • 102
  • 136
  • 1
    Ok, but the pointer to virtual table is not necessary sizeof(void*) (it seemes wrong, for instance, for 16-bit Borland C++ wich uses 2 bytes "short" pointer for this purpose regardless to memory model). It is better to compare with sizeof(SomeEmptyPolimorphicClass) – user396672 Jan 28 '11 at 15:14
-2

The most simple answer to this that both works and is standard complaint: Look at the header files for the class/struct and its class hierarchy. They will tell you if there are data elements (as well as a vtable).

Zac Howland
  • 15,485
  • 1
  • 24
  • 40