Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用子类中的类型定义扩展模板类_C++_Templates - Fatal编程技术网

C++ 使用子类中的类型定义扩展模板类

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:

我模仿了来自_this的
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>
{ /* ... */ };