32

Is there any std::empty struct or something similar or do I need to define my own:

struct empty{}; 

This can be used very nice in combination with std::conditional or other new std features and I wonder if the standard defines it or not.

18
  • 2
    To the best of my knowledge, no. Commented May 21, 2013 at 9:45
  • Do you want a struct which just have no data members (thus have a size of 1), or a truly empty struct? Commented May 21, 2013 at 9:45
  • 3
    Perhaps std::tuple<>? Commented May 21, 2013 at 9:47
  • @KennyTM I don't think it's possible to have truly empty struct and be able to declare variables of that type. I think classes derived from empty struct will optimize it's size and it should behave like "0 size" struct in this case Commented May 21, 2013 at 9:48
  • 1
    @Damon: In which case, the empty object would occupy the unique address that it's given, taking up one byte of address space, wherever you put it. Which is equivalent to saying it has a size of (at least) one byte. (And of course, the compiler can only assign addresses to objects with static storage duration; others get their addresses at runtime). Commented May 21, 2013 at 10:34

4 Answers 4

12

There is a section to add this kind of construct as part of the Variant proposal (n4542).

After being voted on,

What do we want to call the “empty_t” stand-in type?
empty_t 4
empty 4
one_t 1
blank 6
blank_t 7
monostate 7

Runoff:
blank* 3
monostate 8

the agreed upon name would be: std::monostate.


It would be defined the following way:

// 2.?, Explicitly default-constructed alternative struct monostate {}; bool operator<(const monostate&, const monostate&) constexpr { return false; } bool operator>(const monostate&, const monostate&) constexpr { return false; } bool operator<=(const monostate&, const monostate&) constexpr { return true; } bool operator>=(const monostate&, const monostate&) constexpr { return true; } bool operator==(const monostate&, const monostate&) constexpr { return true; } bool operator!=(const monostate&, const monostate&) constexpr { return false; } 
Sign up to request clarification or add additional context in comments.

Comments

10

It is defined as std::monostate in header <variant>

struct monostate { }; 

It is used for example in std::variant ( a type-safe union ), where std::variant<std::monostate> represents an empty variant. Monostate makes variants default-constructible.

Comments

6

EDIT: with the introduction of std::monostate in C++17 this answer is outdated. See other answers for more information.

There is no such a thing in the c++ standard library. As mentioned in the comments, you can still find boost::blank in Boost which is probably what resembles the most to the class you are looking for. If such a class existed in the standard library, I don't think there would be so many third-party libraries defining their own struct empty {}.

If what you want is just a class with no data members and the smallest possible size - cannot be smaller than 1 - (and possibly benefit from the empty base optimization), you can still use std::tuple<>. It is actually used for that exact purpose (empty base optimization) in the implementation of some classes in the libstdc++.

If you want to make sure std::tuple<> really is an empty class:

#include <iostream> #include <tuple> #include <type_traits> int main() { // prints 1 std::cout << std::is_empty< std::tuple<> >::value; } 

Comments

4

If I understand your question correctly, you are looking for an error return type for using with std::conditional. Usually people define their own empty struct types for metaprogramming. This makes sense as it is usually not possible to design metaprogramming libraries in a way that they can easily interact with arbitrary other compile-time libraries.

The closest thing to a de-facto standard is probably Boost.MPL, so using something like mpl::void_ might make sense in your situation.

If you insist on sticking to Standard types, nullptr_t seems to be a good match.

2 Comments

Using nullptr_t for this is actually quite a nice idea.
The only problem of nullptr_t is that, if instanciated, it is required to be as least a large as a void* instance. This shouldn't be a problem if the only use is metaprogramming.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.