【问题标题】:Template class inside class template in c++c++中类模板内的模板类
【发布时间】:2010-11-08 14:46:25
【问题描述】:

这里的菜鸟仍在尝试使用模板。正在尝试写一个消息处理类模板

template <typename T> class MessageProcessor {

  //constructor, destructor defined
  //Code using t_ and other functions
foo( void ) {

//More code in a perfectly fine method
}
  private:  T *t_

};

全部定义在一个头文件中。我已经建立并测试了我的课程,一切都很好。现在,我正在尝试这样做:

template <typename T> class MessageProcesor {

  //Same stuff as before

foo(void) {
//Same code as before in foo, but one new line:
  t_->getMessageSender<MessageType>();

}

private: T *t_;
};

但是,这一行在“>”标记之前给了我一个错误的表达式类型错误。

我添加了必要的头文件来定义 MessageType 是什么。我以前用过这个函数很多次,只是没有在这个上下文中。

我怀疑编译器不喜欢模板函数在未定义的类模板(未专门化?)中完全定义(专门化?)这一事实。我并没有完全理解是什么让模板“专业化”。大多数解释都集中在“完整”或“部分”的概念上,而不是首先使其专业化的原因。

如果您想查看更多代码,我们深表歉意。我在工作中没有互联网接入,这就是我要做的地方,所以我必须把所有东西都放在我的心理“便签本”中并带回家。

【问题讨论】:

  • 这里发布getMessageSender函数代码。
  • 食物没有返回类型,那是你的问题
  • 你们的观察都是正确的。然而,这些都是错别字。实际的问题是缺少 Faisal 回答的“模板”关键字

标签: c++ templates specialization class-template


【解决方案1】:

您的成员函数“foo”需要一个返回类型,当您在依赖表达式(其含义直接或间接依赖于通用模板参数的表达式)中使用成员模板时,您需要使用关键字“模板”

t_->template getMessageSender<MessageType>();  // ok
t_->getMessageSender<MessageType>(); // not ok

当成员模板需要以'template'关键字作为前缀时,也许这个例子会帮助你理解[注意:为了对称,你可以总是在成员上使用'template'前缀模板,但在用于非依赖表达式时是可选的。

struct MyType
{  
  template<class T> void foo() { }
};

template<class U>
struct S
{
  template<class T>
  void bar()
  {
    MyType mt;  // non-dependent on any template parameter
    mt.template foo<int>(); // ok
    mt.foo<int>();  // also ok

    // 't' is dependent on template parameter T
    T t;
    t.template foo<int>();    // ok
    t.foo<int>(); // not ok

    S<T> st; // 'st' is dependent on template parameter T
    st.template foo<int>();    // ok
    st.foo<int>(); // not ok


    S<MyType> s;  // non-dependent on any template parameter
    s.bar<int>(); // ok
    s.template bar<int>(); // also ok

  }

};

希望对您有所帮助。

【讨论】:

  • 您需要在哪个编译器上执行此操作?
  • @Edouard - 仅当从依赖于模板参数的标识符访问成员模板时,该标准才需要“模板”前缀 - 大多数编译器都应该做到这一点,因为这已成为标准的一部分,因为 ' 98 - 在 03 年,为了简单起见,他们修改了规则,以便您可以在所有成员模板访问中使用它 - 以及 EDG 编译器(大多数情况下都正确),我没有在任何一个上检查它其他编译器 - 如果有请告诉我。
【解决方案2】:

-&gt;和模板方法名之间添加关键字template

t_->template getMessageSender<MessageType>();

【讨论】:

    【解决方案3】:

    此时可能不知道 MessageType。您是否缺少包含、命名空间解析或声明?

    如果不是这样,getMessageSender 是如何声明的,MessageType 是如何声明的?

    一般来说,在 C++ 中,如果 T 在那一点上是未知的,这不是问题(嗯……这很复杂,但仍然如此)。

    此外,错误消息通常包含尝试实例化的类型。至少尝试发布完整的错误消息。

    【讨论】:

      【解决方案4】:

      您是否还有其他类似的模板化方法调用,例如 getMessageSender?

      t_->getMessageSender<MessageType>();
      

      【讨论】:

        【解决方案5】:

        只是缺少函数的返回类型。 t_ 成员已完全定义。

        模板的特殊化是您实现特定模板参数的“特殊”版本。例如:std::vector 是通用 std::vector 的专用版本。

        部分特化是泛型代码的一种实现,其中并未提供所有模板参数。

        【讨论】:

          【解决方案6】:

          这在 Visual Studio 2010 编译器上运行良好。

          class One
          {
          public:
              void newFoo() ;
              template < class T > void foo()
              {
                  T obj ;  // obj is dependent on template parameter
                  obj.newFoo() ;  // and this works
              }
          }
          

          只是为了保持答案更新!!!

          【讨论】:

            猜你喜欢
            • 2018-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-01
            相关资源
            最近更新 更多