【问题标题】:Passing a template class as an argument to a function将模板类作为参数传递给函数
【发布时间】:2011-09-17 23:07:55
【问题描述】:

如果我使用模板定义一个类,例如

template<class K, class V>
class myclass {
...
};

有没有办法在不使用函数模板的情况下将 myclass 定义的对象传递给函数?换句话说,对于每个接受 myclass 对象的函数,是否也需要使用 template 来定义它?

这样做的主要原因是我想定义一组作用于 myclass 对象的静态函数,以便我可以将这些函数的范围限制在它们的 cpp 文件中,而不是在头文件中。

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    让你的模板类继承自某个基类:

    template<class K, class V>
    class myclass : mybaseclass { ... };
    

    基类将模板的公共功能声明为纯虚拟。这样一来,KV 的每个组合只有一个函数,而不是一个函数。

    【讨论】:

      【解决方案2】:

      是的,如果您希望您的函数能够接受模板类的任何实例化,它们也必须是模板(通常具有用于该类的相同模板参数)。

      另一方面,您可以让您的模板类继承自非模板类,该类仍然允许您通过虚函数操作派生类。此外,为了隐藏您的类的类型并避免混淆您的所有templates 代码,type erasure 有几种技术。

      【讨论】:

        【解决方案3】:

        不,你不能。类模板不是类——它只是一个模板。只有插入模板参数后,您才会获得一个类型,并且对于每组不同的参数,您会获得一个不同不相关类型。

        也许运行某种类型擦除方案是可行的,通过这种方案,您有一个包含抽象成员指针的容器类,并且对于每种类型,您都实例化一个具体的派生对象。 (查看 Boost.any。)

        有点像这样:

        class MyClassHolder { };
        
        template <typename K, typename V>
        class MyClassConcrete {  };
        
        class MyClass
        {
          MyClassHolder * p;
        
        public:
          template <typename K, typename V> init(...)  // could be a constructor
          {
            p = new MyClassConcrete<K, V>();
          }
        };
        

        现在您可以让您的函数接受MyClass,但您必须向MyClassHolder 添加足够的虚函数,在MyClassConcrete 中实现它们并在MyClass 中公开它们,这样您就可以实现所有您想要的语义。

        【讨论】:

          【解决方案4】:

          不,您还必须将函数模板化(当然,除非它们仅限于使用 myclass 的特定专业化)。

          【讨论】:

          • 在这种情况下,有没有办法声明一个函数,使其范围仅限于在同一个头文件中定义的函数?为头文件寻找等效的“静态”
          • @entitledX:不知道你对 static 的等价物是什么意思,但免费函数总是可以公开访问的,所以不,声明一个函数将允许任何看到声明的代码调用它。
          • 匿名命名空间可用于实现与静态相同的效果,但这并不重要,因为它不会在头文件中按您想要的方式工作。头文件获取,你知道的,包含在各自的源文件中...
          【解决方案5】:

          你可以这样做:

          void myfunc(const myclass<int, int>& mc) {}
          

          只有当您希望能够将任何类型传递给函数中的 myclass 参数时,您才需要将 myfunc 也设为模板。

          【讨论】:

            【解决方案6】:

            由于 C++ 的静态特性,您必须为源代码中的每个 (K, V) 对实例化一个函数副本,因为编译器必须生成代码以不同方式访问每个对的成员。

            【讨论】:

              【解决方案7】:

              虽然您的原因我并不完全清楚,但是,是的,每个将 myclass 作为参数的函数也必须在 K 和 V 上进行模板化。如果您设法抽象基础知识,您可以拥有每个 myclass&lt; K, V &gt; (对于 K 和 V 的每种组合,它是不同的类型)从实现该功能的单个基类继承,或通过虚函数转发它。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2018-09-28
                • 1970-01-01
                • 2015-09-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-12-25
                相关资源
                最近更新 更多