使用C ++模板接口

时间:2014-06-09 10:26:17

标签: c++ templates

我发现模板界面非常优雅,尝试实现它面临着我无法解决的问题。我希望你能为我解释一下。

我有课,例如 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;
    }
};

模板类Smelter没有任何实现和模板类Forge实现。

现在,当我想添加类Iron时,我需要创建iron.h并实现Smelter使用它,这样 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
}

如果所有这些内容都在一个头文件中,那么一切都会完美无缺。但是如果我创建 iron.h 我尝试实现Smelter,编译器找不到模板类Smelter。如果我在forge.h和iron.h中为冶炼厂创建声明副本,那么它们就会相互冲突。

最佳解决方案是什么?如果我能够在其他文件中实现我的模板接口,那将非常有用。如果没有这样的模板,那么接口变得很难看,例如,如果 forge.h 是工具,在项目之间使用,而 iron.h 是我目前的专业化。

结果: 一切都按预期工作,问题超出了描述的问题,在命名空间中。所有模板,即使可以在不同文件之间分开(这是问题) - 完美有效。但是他们必须共享相同的名称空间。

1 个答案:

答案 0 :(得分:1)

在修复了一些小问题之后,你的代码编译得很好(使用clang 3.3)并产生所需的结果。这是固定代码(在一个文件中,但按#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;
}