Implicit creation of function templates when handling them

Note. I already looked here , and I do not think the answer is correct.

What are the rules governing the implicit creation of functions when they are handled? 14.7.1 / 9 of n3242 says the following:

An implementation must not implicitly create a function template, a member template, a non-virtual member function, a member class, or a static data element of a class template that does not require instantiation.

Now, of course, no function definition is required to determine its address. We can take the address of functions declared ahead and define them in another translation unit.

In this case, I do not know when it will be needed. However, compilers seem to have their own idea. Testing for GCC and VC, here are a few examples:

template <typename T> void CallBanana() { T::Banana(); } template <typename T> void CallUnimpl(); template <typename T> struct S { static void CallBanana() { T::Banana(); } static void CallOrange() { T::Orange(); } static void CallUnimpl(); }; struct B { static void Banana() {} }; int main() { (void)(&CallBanana<void>); // 1 (void)(&CallUnimpl<void>); // 2 (void)(&S<void>::CallBanana); // 3 (void)(&S<void>::CallOrange); // 4 (void)(&S<void>::CallUnimpl); // 5 (void)(&S<B>::CallBanana); // 6 } 

They need to be commented - one at a time to see the effects.

GCC 4.7 tested here will complain about 1, 3, and 4. So it creates all the definitions if they exist.

VC 2010 (no online test, sorry) creates instances 3 and 4, but does not create instance 1.

Clang 3.0 tested here has the same behavior as VC 2010.

No compiler complains about 2 or 5, which is what I expect. I would expect it to not be able to reference if I really used these pointers.

All compilers have 6 compilers. I expect this, but it should show that the whole class template is not created (as stated in the answer to this other question) just because I take the address of one function. If the entire template has been created, then S :: CallOrange should not be compiled, because B does not contain an orange function.

Therefore, I am wondering if anyone has a definitive answer regarding proper behavior. The standard, apparently, states that no functions should be created, but three popular compilers are implemented in some cases, but differ from each other.

+7
source share
2 answers

The definition of the function required if you take its address (within the evaluated context).

Of course, a definition can be given in a separate translation unit, but this does not change the fact that a definition is required.

If only one member function is required, this does not mean that other member functions are also created.

If the function template is undefined, it cannot be implicitly created. Then it must be explicitly instantiated into another translation unit. Reliance on implicit creation in another translation unit is prohibited (but diagnostics are not required).

+6
source

You must create an instance because the template extension may not result in formatted code.

In fact, the instance may not even lead to a valid prototype (this failure will qualify as β€œnot a failure”).

(When SFINAE is enabled, the accepted effective address may ignore several earlier candidates in partial ordering (because the replacement error is not an error) before the actual candidate is selected to accept the address.)

0
source

All Articles