3

Lets say that I have this:

struct foo {
    template <typename T>
    void bar(const T param) { cout << param << endl; }
};

Now I want to add the specialization:

template <>
void bar<char>(const char param) { cout << static_cast<int>(param) << endl; }

Can I just add the declaration to the header that foo is declared in and defince bar<char> in the implementation file foo is implemented in?


The reason that I'm asking is that locally I'm seeing it work both ways. I think the difference is: Specialized template methods that I'm only using internally to the defining class can be defined in the implementation. Specialized template methods I'm using externally seem to need to be defined in the header. I haven't been able to find anything conclusive on this though so I thought I'd ask.

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 1
    Note that you have template of member function but seemingly specialize free function. – Öö Tiib Oct 25 '18 at 17:55
  • @ÖöTiib By that, I assume that you mean that it's unclear from my statement, "Now I want to add the specialization" that this is specializing the template method `bar`? – Jonathan Mee Oct 25 '18 at 18:08
  • I mean that your statement contradicts with the code that you posted that tries to specialize `void bar` not `void foo::bar`. – Öö Tiib Oct 25 '18 at 18:14
  • 1
    @πάνταῥεῖ I disagree with closure, as the question is subtly different - OP wants to declare the specialization in the header file, unlike suggested duplicated. I took the liberty of reopening the question, let me know if you disagree. – SergeyA Oct 25 '18 at 18:14
  • @SergeyA Do what you think that's needful. I'll not start arguing. – πάντα ῥεῖ Oct 25 '18 at 18:29

1 Answers1

1

The one thing thy shan't do is to declare specialization in .cpp file. There are good reasons for it, discussed in Explicit specialization of member function template in source file

However, if you put declaration in header file (as I understand you intend to do), the specialization can go into .cpp file, as long as it is called from there at least once - and than you can have calls to the specialization outside of the translation units.

The reason for at least one requirement is that compiler is only going to instantiate the template if it is called and the definition is available, but once template is instantiated, it can be used from any translation units.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • And conversely, if it is used externally? In that case it does need to be defined in the header? – Jonathan Mee Oct 25 '18 at 18:08
  • @JonathanMee as long as the declaration is added to the header file, and the specialized version is called at least once from the defining TU, you should be OK. – SergeyA Oct 25 '18 at 18:11
  • So I'm getting a linker error when `bar` is defined in my .cpp. My understanding from reading your post is that this is because I never call `bar` in the .cpp. Is this correct? – Jonathan Mee Oct 25 '18 at 18:46
  • Assuming that the above is correct is there a way that I can call `bar` in the .cpp such that it will be compiled out? – Jonathan Mee Oct 25 '18 at 18:46
  • 1
    @JonathanMee, yes, this is what I am trying to say. One way of doing that, would be having a dummy function (just make sure it is not static) calling your `bar` with random input, and never call this function. – SergeyA Oct 25 '18 at 18:56
  • Would it be sufficient to write just a function in the .cpp (not a method of `foo`.) So like: `void dummy() { foo{}.bar(); }` – Jonathan Mee Oct 25 '18 at 19:00
  • 1
    @JonathanMee, yes, as long as it is compilable code in the real example. – SergeyA Oct 25 '18 at 19:04