0

there:

What is the result of the following codes?

foo.h

#include <iostream>

template<class _Tp>
struct Foo
{
   void print() { std::cout << "foo\n"; }
};

foo.cxx

#include "foo.h"

template<>
void Foo<int>::print()
{
   std::cout << "foo<int>\n";
}

main.cxx

#include "foo.h"

int main()
{
   Foo<double>().print();
   Foo<int>().print();
   return 0;
 }

The results are different:

  1. when complied by MSVC,

    foo
    foo
    
  2. when compiled by g++,

    foo
    foo<int>
    

I would like to get the second result regardless of compilers. What should I do additionally to achieve? If possible, would you give me an explanation about underlying standards or mechanism. Thank you!

  • 2
    The "result of the following codes" is a compilation error in foo.cxx because it does not contain valid C++ code. – Sam Varshavchik Oct 09 '16 at 03:31
  • I've changed mis-typed: void Foo::void print() --> void Foo::print() Would you see again, thanks. – Dongik Shin Oct 09 '16 at 03:47
  • You just need to declare the specialization in the header file, so that it is visible in all translation units. Add a `template<> void Foo::print();` declaration to the header file. – Sam Varshavchik Oct 09 '16 at 03:50

3 Answers3

1

Your program has undefined behavior.

There are two implementations of Foo<int>::print() -- an inline definition that is obtained from the class template definition and the non-inline definition in foo.cxx. A compiler is free to choose either.

A compiler is not required to diagnose that as a problem. Many of them (apparently that includes g++ and MSVC) choose that route for definitions of class templates and their member functions.

To make sure that both compilers choose the implementation in foo.cxx, declare the function in foo.h.

#include <iostream>

template<class _Tp>
struct Foo
{
   void print() { std::cout << "foo\n"; }
};

template<> void Foo<int>::print();
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thanks but there's a link errors: _unresolved external symbols_ in MSVC, where as it's OK in g++. – Dongik Shin Oct 09 '16 at 04:21
  • @DongikShin, my first reaction is that perhaps foo.cxx is not part of the build. If foo.cxx is part of the build, I can't explain the linker error. – R Sahu Oct 09 '16 at 04:47
0

It is interest. I know that templates are interpreted at compile time, not link time. So, in my opinion, specialization template should implements at each cpp files. What is your g++ version?

seok0721
  • 33
  • 5
0

If the foo.h looks like following, both compilers produce the same results. But I don't know why.

#include <iostream>


template<class _Tp>
struct Foo
{
   void print();
};

template<class _Tp>
void Foo<_Tp>::print()
{
   std::cout << "foo\n";
}

template<> void Foo<int>::print();