问题
Consider this code snippet,
template<bool b>
struct other
{
static const bool value = !b;
};
template<bool b>
struct test
{
static const bool value = b || other<b>::value;
};
int main()
{
bool value = test<true>::value;
}
Do compilers instantiate other<true>
in situations such as the above, when instantiating seems completely unnecessary? Or just because I've written the syntax other<b>::value
, compilers must instantiate it regardless of the fact that it contributes absolutely nothing to the calculation of the value of test<true>::value
?
I would like to hear, a) what is required by the Standard, and b) what is actually implemented by the various compilers? Relevant sections from the Standard would be appreciated.
回答1:
According to the C++ spec, section $14.7.1/4:
"A class template specialization is implicitly instantiated if the class type is used in a context that requires a completely-defined object type or if the completeness of the class type affects the semantics of the program; in particular, if an expression whose type is a class template specialization is involved in overload resolution"
In the case you illustrated with short-circuiting, the class would have to have a complete type, because you're looking inside of it to find the value static member. This precludes the compiler from short-circuiting the expression.
As for what actually happens in practice, I'm not sure because I can't see how the compiler could get away with not doing the instantiation. For example, suppose that the instantiation of other<b>
looked like this:
template <bool B> struct other {
typedef int value;
};
Here, your program would be ill-formed because other<b>
::value is a type, not a value, but the compiler couldn't diagnose the error without actually doing the instantiation.
来源:https://stackoverflow.com/questions/4600565/short-circuiting-while-instantiating-template