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



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

请考虑以下事项:

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!

有什么解决方法吗?

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

作为class A<T>中的嵌套类型,MemberType依赖于模板参数T

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

你想

做什么是不可能的。模板只是一个模板。在实际为具体类型实例化它之前,您几乎无法对它执行任何操作。对于根本没有嵌套MemberTypeA,可能存在专用化。

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

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

邋遢的说话template<typename T>可以理解为"接下来的一切取决于T"。即使你认为它没有,也总会有一个专业化可以改变A内部的任何东西。如果您希望MemberType不依赖于T请在 A 外部声明它。

模板中的所有内容都取决于参数 - 这意味着模板专用化甚至可能没有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;
}

正如其他人所指出的,这有点像一种反模式 - 因为内部类型不依赖于外部模板类的参数。

有什么解决方法吗?

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, "!" );
 }

最新更新