问题
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?
回答1:
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.
回答2:
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
isfalse
] 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.
来源:https://stackoverflow.com/questions/11048827/c11-static-assert-and-functions-to-be-used-therein