7

I have these files :-

1.h :-

#include <iostream>

using namespace std;

template <typename A>
void f() {
  cout<<"generic\n";
}

1.cpp :-

#include "1.h"

template <>
void f<int> () {
  cout<<"for ints only\n";
}

main.cpp :-

#include "1.h"

int main() {
  f<int>();
  return 0;
}

Now, I compile and run these with g++ like this :-

g++ -c 1.cpp -o 1.o 
g++ main.cpp 1.o
./a.out

And I get :-

for ints only

On the other hand, I compile it with icpc like this :-

icpc -c 1.cpp -o 1.o
icpc main.cpp 1.o
./a.out

And I get :-

generic

What does the C++ standard say about this? Is any one compiler "right" and the other "wrong" or is the standard ambiguous on this issue and both are "right" ?

James McNellis
  • 348,265
  • 75
  • 913
  • 977
owagh
  • 3,428
  • 2
  • 31
  • 53
  • I'd believe _g++_ is right here, but the undefined behavior lands are tricky... โ€“ K-ballo Jun 21 '12 at 19:05
  • 2
    In the eloquent words of the C++ language standard: When writing a specialization / be careful about its location / or to make it compile / will be such a trial / as to kindle its self-immolation. โ€“ James McNellis Jun 21 '12 at 19:08
  • @K-ballo That's what I'd believe too. But I'd like a pointer to an authoritative source that states this one way or another. โ€“ owagh Jun 21 '12 at 19:10

1 Answers1

11

Your program exhibits undefined behavior. The specialization must be declared in every translation unit in which it is used, per C++11 ยง14.7.3/6:

If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.

James McNellis
  • 348,265
  • 75
  • 913
  • 977