我正在尝试使用模板类的成员类型,该类型不依赖于模板类的任何模板参数。由于其逻辑,我想将该类型保留为成员类型,但是每当我想在类之外使用成员类型时,我都不想指定类的不必要的模板参数。
请考虑以下事项:
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>
是不同的类。
做什么是不可能的。模板只是一个模板。在实际为具体类型实例化它之前,您几乎无法对它执行任何操作。对于根本没有嵌套MemberType
的A
,可能存在专用化。
由于其逻辑,我想将该类型保留为成员类型, [...]
。但似乎逻辑是另一回事: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, "!" );
}