C++ 使用子类中的类型定义扩展模板类
我模仿了来自_this的C++ 使用子类中的类型定义扩展模板类,c++,templates,C++,Templates,我模仿了来自_this的std::enable_shared_来创建一个模板类,但我让该类在其子类中使用类型定义。 不幸的是! 虽然我使用了typename,但编译之后 // // https://ideone.com/eYCBHW http://ideone.com/eYCBHW #包括 #包括 #包括 使用名称空间std; 模板结构A{ }; 模板 类全局{ 公众: typedef typename_子类::connection_t connection_t; //映射连接; //std:
std::enable_shared_来创建一个模板类,但我让该类在其子类中使用类型定义。
不幸的是!
虽然我使用了typename
,但编译之后
//
// https://ideone.com/eYCBHW http://ideone.com/eYCBHW
#包括
#包括
#包括
使用名称空间std;
模板结构A{
};
模板
类全局{
公众:
typedef typename_子类::connection_t connection_t;
//映射连接;
//std::设置连接;
//使用typename\u子类::connection\u t;
//typename _子类::connection _t*connections;
//连接_t*连接;
};
类C连接{};
类连接;
类客户端:公共全局{
公众:
类型定义C连接\u t;
};
#如果0
类服务器:公共全局{
公众:
类型定义连接连接;
};
#恩迪夫
类连接{};
int main(){
//你的密码在这里
返回0;
}
GCC抱怨:
prog.cpp: In instantiation of ‘class Global<Client>’:
prog.cpp:25:23: required from here
prog.cpp:14:43: error: invalid use of incomplete type ‘class Client’
typedef typename _Subclass::connection_t connection_t;
^~~~~~~~~~~~
prog.cpp:25:7: note: forward declaration of ‘class Client’
class Client : public Global<Client> {
^~~~~~
prog.cpp:在“类全局”的实例化中:
程序cpp:25:23:此处需要
程序cpp:14:43:错误:不完整类型“类客户端”的使用无效
typedef typename_子类::connection_t connection_t;
^~~~~~~~~~~~
程序cpp:25:7:注:“类客户端”的转发声明
类客户端:公共全局{
^~~~~~
如何解决
参考资料
在类级别拥有typedef
要求模板参数为完整类型。否则,编译器将如何检查作为参数提供的类型本身是否具有一些等效的typedef
类似地,以下几点也将失败:
class C;
using G = Global<C>; // C is not a complete type!
class C // too late...
{
// ...
};
将其编译为:
class C
{
inline void f();
int n = 10;
};
void C::f() { n = 12; } // n is known now!
这同时也是您可以按预期方式使用模板参数的线索:
template<class T> // different name used! *)
class Global
{
public:
void f()
{
typedef typename T::connection_t connection_t; // possible here!
// (similar to why you can use the static cast as in the link provided)
}
};
否则,您需要退回到其他方法,例如,让实现类从模板继承
*)以下划线开头,后跟大写字母的标识符,以及包含两个后续标识符的标识符,都是为实现保留的(即供编译器使用)。定义自己的标识符会产生未定义的行为
编辑(摘自评论):
如果您需要从全局
中使用客户端或服务器,您还可以将两者作为单独的模板参数提供:
template <typename Base, typename Connection>
{
// use Connection directly, e. g. for member definitions
// and Base within member functions as mandated by CRTP
};
class Client : public Global<Client, CConnection>
{ /* ... */ };
模板
{
//直接使用连接,例如用于成员定义
//以及CRTP规定的成员职能范围内的基础
};
类客户端:公共全局
{ /* ... */ };
请注意,以下划线开头,后跟大写字母(\u S
,\u Subclass
!)的标识符以及包含两个后续下划线的标识符是为实现保留的(即编译器)不幸的是,C++没有这样的工作。一个类不能被定义直到它的超类被定义。因此,你不能引用它的超类中定义的东西,使用CRTP设计模式。没有解决方案。你必须重新构造事物,不知怎么解释。你能解释一下你想要实现的吗?,拜托?从代码上看我不清楚…从我收集的信息来看,你想要的是CRTP…@SamVarshavchik你可以从它的超类中引用在子类中定义的东西,这就是CRTP的全部要点。但是你只能在超类成员函数中做。那么模板类全局
呢?很好!我必须这样做s、 添加模板参数
template<class T> // different name used! *)
class Global
{
public:
void f()
{
typedef typename T::connection_t connection_t; // possible here!
// (similar to why you can use the static cast as in the link provided)
}
};
std::map<std::string, typename T::connection_t> connections;
// ^ additionally was missing, but won't help either
template<class T> // different name used! *)
class Global
{
std::map<std::string, T> connections;
// ^ use T directly
};
class Client : public Global<CConnection>
// ^ make sure it is defined BEFORE
{
// ...
};
template <typename Base, typename Connection>
{
// use Connection directly, e. g. for member definitions
// and Base within member functions as mandated by CRTP
};
class Client : public Global<Client, CConnection>
{ /* ... */ };