【问题标题】:Class templating std::set key types类模板 std::set 键类型
【发布时间】:2010-12-23 00:44:46
【问题描述】:

我有一个类来评估集合代数,但希望对其进行模板化。

现在看起来有点像这样

set.h:

template<typename T>
  class SetEvaluation
  {
  public:
    SetEvaluation<T>();

    std::set<T>
    evaluate(std::string in_expression);
   }

set.cpp

template<typename T>
   std::set<T>
   SetEvaluation<T>::evaluate(std::string expression)
   {
     std::set<T> result;
     etc etc...
   }

但是我在编译时遇到了未定义的引用错误。

是否可以将返回类型声明为 std::set,然后将 std::string 作为类模板参数传递。

类中没有错误,但只有当我尝试实例化 SetEvaluation<:string>

谁能解释一下这个问题?

谢谢

【问题讨论】:

    标签: c++ templates class


    【解决方案1】:

    模板类和函数有点特殊,需要在头文件中定义。然后,无论您想在哪里使用该模板类,都需要将该头文件#included。如果您尝试在链接器的 cpp 文件中定义模板函数并尝试从另一个 cpp 文件调用该函数,则链接器将无法解析引用,因为编译器不知道参数 T 使用什么当它编译带有模板定义的文件时。解决此问题的最佳方法是 1) 在头文件中定义函数和 2) 在需要的地方 #include 它。在C++ faq 上有关于此问题的更多信息。

    琐事

    还有另一种方法可以使用 Comeau C++ 编译器解决此问题,因为它支持“export”关键字,但该关键字在 C++0X 中已被弃用。

    【讨论】:

      【解决方案2】:

      分号;之后

      template<typename T>
        class SetEvaluation
      

      在.h中

      并定义一个构造函数 至少是一个空的或将其注释掉

      public:
          SetEvaluation<T>() {}
      

      好的,在这种情况下,使用希望从其他文件中使用它。在这种情况下,您必须 在 .cc 文件中使用此语法显式实例化此模板:

      template std::set<std::string> SetEvaluation<std::string>::evaluate(std::string expression);
      

      或者你必须把定义放到头文件中

      【讨论】:

      • 感谢您的快速响应。这两个我都有,我只是把代码删掉了,把它作为示例发布在这里。
      • 您有两个选择:显式实例化或将所有内容放在标题中。如果你想使用更多类型,更好的选择是标题之一。
      • 所以我整个班级的代码都必须在头文件中?这似乎有点愚蠢。感谢您的帮助:)
      • 是的,在这种情况下,您可以使用每种类型,但编译过程会慢很多。使用显式实例化编译会更快,但您必须为该 cc 文件中的每种类型进行实例化。
      【解决方案3】:

      对于通用解决方案,将模板方法定义为头文件中的内联方法,无论是在类主体中还是在其之后: [对于给定的编译器系统,您也许可以这样做。]

      template<typename T>
        class SetEvaluation
        {
        public:
          SetEvaluation<T>() { etc. etc.}
      
          std::set<T>
          evaluate(const std::string& in_expression);
         };
      
      template<typename T>
         inline std::set<T>
         SetEvaluation<T>::evaluate(const std::string& expression)
         {
           std::set<T> result;
           // etc etc...
         }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-06
        • 2022-07-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多