4

In a header file of a large project, I have to forward declare a function template before the calling site. The code boils down to this:

//H1.h

#pragma once

template <typename>
void f();

inline void g()
{
    f<void>();
}
//POI #1

template <typename>
void f()
{}
//TU1.cpp

#include "H1.h"

void func1()
{
    g();
}

//(End of TU) POI #2
//TU2.cpp

#include "H1.h"

void func2()
{
    g();
}

//(End of TU) POI #3

As I understand, #1, #2 and #3 are three POIs for f. At POI #1, f is not defined yet. After the definition of f, there is no explicit instantiation to tell the compiler to instantiate f<void> specifically. Does the compiler remember to generate code for f<void> at the end of TU? The testing result is yes, at least when using GCC, clang, or MSVC.

But the question is: is this declare-call-define pattern for function template standard conformant?

I'm not a standard expert but I searched the standard text to look for relevant words, and only found this rule for when using explicit instantiation. But I'm not sure the case when the template is implicit instantiated.

zwhconst
  • 1,352
  • 9
  • 19
  • Why you combine two questions? I vote to close for focus. Yes it is kosher, see https://stackoverflow.com/questions/7255281/necessity-of-forward-declaring-template-functions Templates and inlines are immune to ODR unless you really define those to conflict in different translation units. – Öö Tiib Aug 15 '23 at 07:54
  • @ÖöTiib Thanks for the hint. I have removed question 2. – zwhconst Aug 15 '23 at 08:19
  • OK, I retract vote. – Öö Tiib Aug 15 '23 at 08:43
  • Template instantiation phase follows syntactic and semantic analysis phase, so this looks like you can haz template definition located after its first «use». https://timsong-cpp.github.io/cppwp/n4868/lex.phases#1.7.sentence-3 https://timsong-cpp.github.io/cppwp/n4868/lex.phases#1.8 – Language Lawyer Aug 15 '23 at 09:02
  • 1
    See also https://timsong-cpp.github.io/cppwp/n4659/temp#7 – Language Lawyer Aug 15 '23 at 09:11

0 Answers0