4

I have this code:

#include <iostream>

struct A
{
    template<typename T> bool isImplemented()
    {
                std::cout << "Not Implemented" << std::endl;
                return false;
    }
};

template<> inline bool A::isImplemented<int>()
{
    std::cout << "int Implemented" << std::endl;
    return true;
}

I can understand why the template specialization needs the inline, in order to prevent the ODR to be violated the inline will merge the translation table avoiding a conflict.

But, why I don`t need an inline on the isImplemented inside the struct A? Maybe that question can be extended to, why if the method is declared inside the struct/class on the header it does not need the inline? As I can understand, it would create the symbols on every object file (.o) that it is called, violating the ODR, why that does not happen?

Lefsler
  • 1,738
  • 6
  • 26
  • 46
  • 3
    Anything with a template parameter is essentially implicitly `inline`. – aschepler Apr 10 '17 at 13:15
  • 2
    The template specialization is a function. The template is a template. Templates aren't functions, and vice versa. Templates follow different rules. – Kerrek SB Apr 10 '17 at 13:16
  • @KerrekSB that actually helps a LOT, thanks. I was having issues trying to understand why I only need that on specializations. I imagine that this is the same rule applied when you declare friend operators and you need to use inline in order to prevent the violation on the ODR, right? – Lefsler Apr 10 '17 at 13:17

2 Answers2

3

You do not need it for two reasons:

  • Every function defined within the definition of the class is implicit inline.
  • A template doesn't need inline keyword. Remember, your original function is a template, while specialization is not.
SergeyA
  • 61,605
  • 5
  • 78
  • 137
1

The point to highlight here is that template<typename T> bool isImplemented() IS NOT a function. It is a template to a function and will only exist (as code) once specialized, like you did with template<> inline bool A::isImplemented<int>().

The inline here is not mandatory. Program compiles and runs perfectly without it.

Strangely your struct A does not depend on any template parameter neither isImplemented() method so I am still trying to figure out your intention.

A simple usage of your functions might look like this:

int  main( )
{
    A a;

    a.isImplemented< int >( );
    a.isImplemented< double >( );
}

And the output:

int Implemented
Not Implemented

And basically you are able to tell wich specializations you have explicitly implemented from the generic ones. Is it what you need?

EDIT:

Given the comment on my answer, I believe the original question is nicely answered here:

Community
  • 1
  • 1
j4x
  • 3,595
  • 3
  • 33
  • 64
  • Actually, this is a code that I wrote to understand the inline and the ODR. That is why it is like that. It comes from a problem that I had long time ago trying to specialize something based on the return type. – Lefsler Apr 10 '17 at 14:27