Undefined template methods trick ?

Posted by Matthieu M. on Stack Overflow See other posts from Stack Overflow or by Matthieu M.
Published on 2010-05-09T11:49:18Z Indexed on 2010/05/09 11:58 UTC
Read the original article Hit count: 201

Filed under:
|
|
|

A colleague of mine told me about a little piece of design he has used with his team that sent my mind boiling. It's a kind of traits class that they can specialize in an extremely decoupled way.

I've had a hard time understanding how it could possibly work, and I am still unsure of the idea I have, so I thought I would ask for help here.

We are talking g++ here, specifically the versions 3.4.2 and 4.3.2 (it seems to work with both).

The idea is quite simple:

1- Define the interface

// interface.h
template <class T>
struct Interface
{
  void foo(); // the method is not implemented, it could not work if it was
};

//
// I do not think it is necessary
// but they prefer free-standing methods with templates
// because of the automatic argument deduction
//
template <class T>
void foo(Interface<T>& interface) { interface.foo(); }

2- Define a class, and in the source file specialize the interface for this class (defining its methods)

// special.h

class Special {};


// special.cpp

#include "interface.h"
#include "special.h"

// 
// Note that this specialization is not visible outside of this translation unit
//
template <>
struct Interface<Special>
{
  void foo() { std::cout << "Special" << std::endl; }
};

3- To use, it's simple too:

// main.cpp

#include "interface.h"

class Special; // yes, it only costs a forward declaration
               // which helps much in term of dependencies

int main(int argc, char* argv[])
{
  Interface<Special> special;
  foo(special);
  return 0;
};

It's an undefined symbol if no translation unit defined a specialization of Interface for Special.

Now, I would have thought this would require the export keyword, which to my knowledge has never been implemented in g++ (and only implemented once in a C++ compiler, with its authors advising anyone not to, given the time and effort it took them).

I suspect it's got something to do with the linker resolving the templates methods...

  • Do you have ever met anything like this before ?
  • Does it conform to the standard or do you think it's a fortunate coincidence it works ?

I must admit I am quite puzzled by the construct...

© Stack Overflow or respective owner

Related posts about c++

Related posts about g++