Reputation: 2207
I found template interfaces very elegant, and trying implementing it faced problem that I can't solve. I hope you can shed some light on it for me.
I have class, for example, forge.h:
template<typename T> class Smelter;
template <typename T>
class Forge
{
long SmeltIt(vector<T>& ore)
{
long res;
Smelter<T> smelter;
for (const auto t : ore)
{
res += smelter.smelt(t);
}
return res;
}
};
With template class Smelter without any realization and template class Forge with realization.
Now, when I want to add class Iron, I need to create iron.h and implement Smelter to use it, this way iron.h:
#include "forge.h"
class Iron {};
template<>
class Smelter<Iron>
{
long smelt(const Iron& iron) { return 5; }
};
int main()
{
vector<Iron> ore;
Iron iron;
ore.push_back(iron);
ore.push_back(iron);
ore.push_back(iron);
Forge<Iron> forge;
cout << forge.SmeltIt(ore); //have to be 15
}
If all this stuff is in one header file, everything perfectly works. But if I create iron.h where I try to implement Smelter, compiler can't find template class Smelter. If I create copy of declaration for Smelter in both forge.h and iron.h, then they conflict with each other.
What is the best solution for that? It would be very useful if I would be able to realize my template interface in other files. Without this such template interfaces becomes ugly, for example, if forge.h is tools, wirely used between projects, and iron.h is my current specialization.
RESULT: Everything works as expected, problem was outside of described question, in namespaces. All templates, even if it is possible to separate them between different files (that was question) - perfectly works. But they have to share same namespaces.
Upvotes: 0
Views: 99
Reputation: 45424
after fixing some minor issues, your code compiles fine (using clang 3.3) and produces the required result. here is the fixed code (in one file, but in the order of #include)
template<typename T> class Smelter;
template <typename T>
class Forge
{
public:
long SmeltIt(std::vector<T>& ore) // must be public; use std::
{
long res{}; // must be initialized (to 0)
Smelter<T> smelter;
for (const auto t : ore)
res += smelter.smelt(t);
return res;
}
};
class Iron {};
template<>
class Smelter<Iron>
{
public:
long smelt(const Iron& iron) // must be public
{ return 5; }
};
int main()
{
std::vector<Iron> ore; // std::
Iron iron;
ore.push_back(iron);
ore.push_back(iron);
ore.push_back(iron);
Forge<Iron> forge;
std::cout << forge.SmeltIt(ore) // have to be 15
<< std::endl;
}
Upvotes: 1