2

static_assert seems to be a very nice feature together with templates.

However, I have trouble finding functions in the standard library for doing various tests at compile time.

For example, I am looking for a function to check whether a type is a subtype of another one. boost::is_base_of does the job, however, is a comparable function in std, so I do not need to rely on boost.

Basically, is there a good source for a list of functions which can be used in static_assert and are contained in the standard library of C++11?

When is static_assert executed? Can I put it anywhere in a template and it is evaluated for each template instanciation? Could it be used to constrain template parameters to be a specific subtype of a class?

superM
  • 8,605
  • 8
  • 42
  • 51
gexicide
  • 38,535
  • 21
  • 92
  • 152

2 Answers2

8

Take a look at the final C++11 draft, section 20.7, particularly the <type_traits> header.

What you are asking is: std::is_base_of<base, derived>::value;

Regarding your question: static_assert can be evaluated whenever the compiler sees fit, but it will usually:

  • In a template: if the expression uses dependent names, in instatiation time; else, in definition time.
  • Out of template: in definition time.
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • perfect, thanks! That was exactly what I was looking for. Could I use it to constrain the type parameter of a template? – gexicide Jun 15 '12 at 10:25
  • 1
    @gexicide - Yes, that's actually the reason to be for . – rodrigo Jun 15 '12 at 10:32
  • 2
    n3092 is actually from about a year before the final draft. n3290 is the most recent available draft from before the standard was finished. You should probably use n3337, which is from immediately after standardization, and the only differences from the official standard are corrected typos and the like. – bames53 Jun 15 '12 at 13:05
  • @bames53 - Thank you for the clarification. Link updated to the n3242, that seems to be the latest public available. I simply copied the link from the Wikipedia (updated also). The thing is that I have downloaded the actual n3290 draft, but it seems to have been removed. – rodrigo Jun 15 '12 at 22:08
  • 1
    You can get n3337 [here (5MB pdf)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf). There have been more updates and even bug fixes voted in to later versions of the working paper, and some compilers even implement them, but this is the closest document to the official standard that's freely available since n3290 was taken down. – bames53 Jun 15 '12 at 23:00
  • 1
    Oh, and if anyone cares the actual TeX source for the standard is now on GitHub, care of the current editor: https://github.com/cplusplus/draft – bames53 Jun 15 '12 at 23:02
5

In addition to @rodrigo’s answer (he was faster …),

When is static assert executed? Can I put it anywhere in a template and it is evaluated for each template instanciation? Could it be used to constrain template parameters to be a specific subtype of a class?

Unfortunately, no. For instance, a static_assert(false, "bummer"); is always executed, no matter the template. This in particular fails if you want to (partially) specialise a template.

The standard (§7.4) says:

[If the condition to static_assert is false] the program is ill-formed, and the resulting diagnostic message (1.4) shall include the text of the string-literal, […]

Which is unfortunately quite unspecific but this lack of specificity is in fact exactly how static_assert behaves when it’s not dependent on a template type.

You need to make the condition in a static_assert depend on the template argument to bind its execution to the particular template argument.

So the following would fail:

template <typename T>
struct some_type {
    static_assert(false, "T must be a pointer type");
};

template <typename T>
struct some_type<T*> {
    // …
};

Finally, I heartily recommend you read Marthino’s article on More type traits which details this process more, and gives hints on how to solve many trait-related problems elegantly.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214