2

Is it possible to declare that a symbol is an explicit instantiation of a function template, without defining the function template first?

It would express to the compiler that there exists a function template in another translation unit that is instantiated somewhere, and we want to call the instantiated function.

// declaration of instantiation, perhaps it would look like one of these:
// template<typename> void foo(int);
// template<typename> void foo<int>(int);

void bar(int i) {
    // definition of function unknown to caller, it shouldn't matter
    foo(i);

    // either that or this perhaps:
    foo<int>(i);
}

Is there a technical reason this can't be done or is it just for lack of syntax? Is there a reason that it's not possible to provide sufficient information in a declaration to generate calls to an instantiated function template?

There is no Y behind this X. This question is meant literally. It's an abstract question about the C++ language. I could provide an example that doesn't compile but that would just be a distraction.

The question is also not about specialization per se. Whether the template was specialized shouldn't matter. This question is only concerned with declaring that a template exists and that it was instantiated.

Related question: How do I explicitly instantiate a template function? - however that does not solve this problem, as it requires the full template definition to be visible.

Community
  • 1
  • 1
Praxeolitic
  • 22,455
  • 16
  • 75
  • 126
  • What is the higher level goal you're trying to accomplish here? You may need to be a bit more explicit with your examples--exactly what doesn't work? I'm about 70% clear on what you're asking now. :) – John Zwinck Oct 02 '14 at 04:34
  • Note that declaring an explicit instantiation is redundant if you only need to call the function, e.g. this is correct and instantiates: `template void foo(T t); void bar() { foo(5); }` – M.M Oct 02 '14 at 04:49
  • @MattMcNabb I actually had a link to that question in the first draft of this question but thought it was extraneous. – Praxeolitic Oct 02 '14 at 04:49
  • Comments addressed in edit. – Praxeolitic Oct 02 '14 at 04:56
  • @MattMcNabb If this isn't possible then the question is why. The key part is that the template has been instantiated with known parameters. – Praxeolitic Oct 02 '14 at 05:03
  • @Praxeolitic I have edit the question with what your intent seems to be (sorry - did it in parallel to your latest edit) to clarify - if I have missed the mark then feel free to roll it back – M.M Oct 02 '14 at 05:19
  • @MattMcNabb Looks good. (You clobbered my other parallel edit!) – Praxeolitic Oct 02 '14 at 05:23

2 Answers2

1

You can use "extern template" here. It tells the compiler not to instantiate it in every translation units. This is part of C++11 enhancements. For example, we may declare the template in a header file a.hpp as

// a.hpp
template <class T>
T fun(T& a);

Then in a.cpp

// a.cpp
#include "a.hpp"
extern template int fun(int&);
int main()
{
   int a = 100;
   return fun(100);
}

And in b.cpp we can actually instantiate the template:

// b.cpp
#include "a.hpp"

template <>
int fun(int& x)
{
    return x + 1;
}
Nipun Talukdar
  • 4,975
  • 6
  • 30
  • 42
  • Neat. Seems to work with explicit instantiation too. But the template definition still must be visible. I don't understand why. – Praxeolitic Oct 02 '14 at 05:51
  • After experimenting: If you forward declare the template and make the extern template declaration, you don't need the template definition to be visible to the caller. – Praxeolitic Oct 02 '14 at 05:59
  • In `b.cpp` you have an explicit specialization of a `fun` function template not an instantiation. And explicit specialization should be declared before the first use of it so your code is ill-formed. – Constructor Oct 02 '14 at 12:23
  • @Constructor yes. I just tried to explain the new enhancement where instantiation in every translation unit can be avoided with C++11 and was relevant to the question. – Nipun Talukdar Oct 02 '14 at 14:18
0

To add to Nipun Talukdar's answer, there's no need for specialization or for the template definition to be visible to the caller.

a.cpp

template<class T> T fun(T);
extern template int fun(int);

int main() {
    // this works, even though we have no idea how fun() is defined
    fun(100);
    // this would fail to link
    // fun('a');
}

b.cpp

template<class T>
T fun(T x) {
    return x;
}

// explicit instantiation
template int fun<int>(int x);
Praxeolitic
  • 22,455
  • 16
  • 75
  • 126