调用类模板的成员函数模板

时间:2017-07-23 13:35:36

标签: c++ templates function-templates

我有以下程序(对不起,它相当复杂,但已经是一个较大程序的简化版本):

#include <stdio.h>

// two different vector types

template <typename T, int N>
struct Vec1
{
  Vec1() { puts("Vec1()"); }
};

template <typename T, int N>
struct Vec2
{
  Vec2() { puts("Vec2()"); }
};

// a function wrapper

template <typename T, int N>
struct MyFct
{
  template <template <typename, int> class VEC>
  static inline VEC<T,N>
  apply()
  {
    puts("MyFct::apply()");
    return VEC<T,N>();
  }
};

// tester

#if 0
template <typename T, int N, template <typename, int> class FCT>
struct Tester
{
  static inline void test()
  {
    puts("Tester::test");
    Vec1<T,N> v1;
    v1 = FCT<T,N>::apply<Vec1>();
    Vec2<T,N> v2; 
    v2 = FCT<T,N>::apply<Vec2>();
  }
};
#endif

int
main()
{
  MyFct<float,16>::apply<Vec1>();
  MyFct<int,32>::apply<Vec2>();
  // Tester<float,16,MyFct>::test();
  return 0;
}

该程序使用#if 0(不使用Tester)进行编译,但使用#if 1(使用Tester)我收到错误消息

g++ -Wall -o templatetemplate2a templatetemplate2a.C
templatetemplate2a.C: In static member function 'static void Tester<T, N, FCT>::test()':
templatetemplate2a.C:41:30: error: missing template arguments before '>' token
     v1 = FCT<T,N>::apply<Vec1>();
                              ^
templatetemplate2a.C:41:32: error: expected primary-expression before ')' token
     v1 = FCT<T,N>::apply<Vec1>();
                                ^
templatetemplate2a.C:43:30: error: missing template arguments before '>' token
     v2 = FCT<T,N>::apply<Vec2>();
                              ^
templatetemplate2a.C:43:32: error: expected primary-expression before ')' token
     v2 = FCT<T,N>::apply<Vec2>();

这是令人惊讶的,因为main()apply<Vec1>()直接应用程序(请参阅apply<Vec2>())工作正常。但是,如果我在Tester::test()内执行相同操作,则会收到错误消息。这是一些名称范围问题吗? Vec1内的模板类Vec2Tester是否未知?我怎样才能让他们知道?还是有其他问题吗?

1 个答案:

答案 0 :(得分:3)

apply()是一个成员函数模板,当使用依赖名称调用它时,需要使用keyword template告诉编译器它是一个模板。请注意FCT<T,N>MyFct<float,16>之间的区别,前者取决于模板参数FCTTN,而后者则不然。

  

在模板定义中,模板可用于声明从属名称是模板。

e.g。

v1 = FCT<T,N>::template apply<Vec1>();
v2 = FCT<T,N>::template apply<Vec2>();