如何在不指定不必要的模板参数的情况下使用模板类的成员类型?

时间:2019-06-18 08:29:28

标签: c++ templates generic-programming

我正在尝试使用模板类的成员类型,该成员类型不依赖于模板类的任何模板参数。由于其逻辑性,我想将类型保留为成员类型,但是每当要在类外部使用成员类型时,我都不想指定该类不必要的模板参数。

请考虑以下内容:

class Dummy { };

// Template class
template<typename T>
class A {
  public:

    template<typename T2>
    class MemberType : public T2 {
      public:
        T2 t2;
    };

};

int main()
{
  typename A<Dummy>::template MemberType<Dummy> m1; // okay
  typename A::template MemberType<Dummy> m2;        // not okay!

  return 0;
}

当我尝试使用g ++进行编译时,出现以下编译器错误:

error: ‘template<class T> class A’ used without template parameters
   typename A::template MemberType<Dummy> m2; // not okay!

有什么解决方法吗?

4 个答案:

答案 0 :(得分:1)

  

我正在尝试使用模板类的成员类型,   取决于模板类的任何模板参数。

作为 <ion-img [src]="images"></ion-img> 中的嵌套类型,class A<T> 确实取决于模板参数MemberType

TA<T>::MemberType<T2>是不同的类。

答案 1 :(得分:1)

中的所有内容都取决于参数-意味着甚至可能没有class MemberType

但是您可以设置一个默认参数-虽然您仍然需要写<>(但是您通常可以省略template-甚至省略typename,但我还是忽略了):

class Dummy { };

// Template class
template <class T = void>
class A {
  public:

    template<typename T2>
    class MemberType : public T2 {
      public:
        T2 t2;
    };

};

int main()
{
  typename A<Dummy>::MemberType<Dummy> m1; // okay
  typename A<>::MemberType<Dummy> m2;        // also ok

  return 0;
}

正如其他人指出的那样,尽管这看起来有点像反模式-因为内部类型不依赖于外部模板类的参数。

答案 2 :(得分:0)

您无法执行的操作。模板只是一个模板。在为具体类型实际实例化它之前,您几乎无能为力。 A可能有一个完全没有嵌套的MemberType的专业化。

  

由于其逻辑,我想将类型保留为成员类型,   [...]

...但是似乎逻辑是另外一回事:MemberType不依赖于A,因此它不应成为依赖于A的模板的一部分。

粗俗的template<typename T>可以理解为“ 一切取决于T”。即使您认为没有,也可能总有一种专长会更改A内部的任何内容。如果您希望MemberType不依赖T,请在A外部声明它。

答案 3 :(得分:0)

  

有什么解决方法吗?

MemberType是依赖于模板参数的类型,因此,您必须通过包含模板的模板参数来对其进行定义

typename A<SomeType>::template MemberType<AnotherType> m2;

考虑到您对外部SomeType参数不感兴趣,我能想到的最佳解决方法是按如下方式使用using(或类似方法)

template <typename T>
using MemberType_t = typename A<T>::template MemberType<T>;

减少打字。

以下是完整的简化示例

#include <type_traits>

class Dummy { };

template <typename>
struct A
 {
   template <typename T2>
   struct MemberType : public T2
    { T2 t2; };
 };

template <typename T>
using MemberType_t = typename A<T>::template MemberType<T>;

int main ()
 {
   typename A<Dummy>::template MemberType<Dummy> m1;

   MemberType_t<Dummy> m2; // compile

   static_assert( std::is_same<decltype(m1), decltype(m2)>::value, "!" );
 }