문제

I'm using the following pattern to keep template declarations and implementations separate:


decl.h (declaration)

template <typename T>
struct Foo
{
  void DoIt();
}

impl.cpp (implementation)

template <typename T>
void Foo<T>::DoIt() { // impl code 
};

template class Foo<int>;
template class Foo<float>;

Now i want to add a new method to Foo, but the impl.cpp file is already huge, so i want to move it to a separate file impl2.cpp;


decl.h (declaration)

template <typename T>
struct Foo
{
  void DoIt();
  void RemoveIt();
}

impl.cpp (implementation)

template <typename T>
void Foo<T>::DoIt() { // impl code 
};

template class Foo<int>;
template class Foo<float>;

impl2.cpp (implementation)

template <typename T>
void Foo<T>::RemoveIt() { // impl code 
};

template class Foo<int>;
template class Foo<float>;

the main concern here are the duplicate instantiations, how do i avoid those?

도움이 되었습니까?

해결책

Do as follows:

  1. Move definition of Foo<T>::DoIt() to some header file named ImplDoIt.h (not necessarily in the same directory as decl.h)
  2. Same for Foo<T>::RemoveIt() - ImplRemoveIt.h
  3. Include in your impl.cpp all these header files and instantiate the templates.

다른 팁

You need to include the implementations for general template argument T into the header and the explicit instantiations for int and float in a source file.

// decl.h
template <typename T>
struct Foo
{
  void DoIt();
  void RemoveIt();
}

#include "impl1.ipp"
#include "impl2.ipp"

// impl1.ipp
template <typename T>
void Foo<T>::DoIt() { // impl code 
};

// impl2.ipp
template <typename T>
void Foo<T>::RemoveIt() { // impl code 
};

// inst.cpp
#include "decl.h"
template class Foo<int>;   // explicit instantiation goes in source file
template class Foo<float>; // explicit instantiation goes in source file

// main.cpp
#include "decl.h"

int main()
{
    // call with concrete template arguments
    Foo<int>::DoIt();
    Foo<float>::RemoveIt();
}

Why? Because DoIt and RemoveIt are functions templates, not functions, and they cannot be compiled before seeing the template T being passed to them. So all clients of Foo need to include not only your header but also your implementation files. The most convenient way is to let the header include the implementations. That's why I renamed them to .ipp.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top