这是我要完成的工作的示例:
#include <iostream>
using namespace std;
template <typename Tmsg>
class MessageParser{
public:
virtual Tmsg Deserialize(const char *buf, size_t len);
};
class JsonParser : MessageParser<int>{
public:
int Deserialize(const char *buf, size_t len) override { return 1; };
};
template <class Tmsg>
using rpc_handler_t = void (*)(Tmsg);
template <typename Tmsg, template <typename> class Tparser>
class RpcServer{
public:
RpcServer(Tparser<Tmsg> parser) : _parser(parser) {};
Tparser<Tmsg> _parser;
void RegisterHandler(rpc_handler_t<Tmsg> handler);
};
int main()
{
JsonParser parser;
RpcServer<int, JsonParser> server(parser);
cout << "Hello World";
}
首先,类模板参数推导似乎是 C++17 的特性。我被 C++11 困住了。编写 RpcServer(parser)
并将其识别为 RpcServer<int, JsonParser>
真是太好了。
以上给了我:
class "JsonParser" is not a class template
好吧,这是真的。但这又有什么关系呢?为什么 JsonParser
作为 MessageParser<JsonObject>
不满足模板?
答案 0 :(得分:0)
它不满足模板,因为这个语法无效:
JsonParser<int> parser;
如您所见,它无法编译。它的基类是什么以及该基类的性质无关紧要。 JsonParser
本身不是模板。你不能向它发送模板参数。
如果可能,这段代码会做什么?
template<typename T>
struct Base {
T value = {};
};
// Derived extend `Base<int>`. Therefore Derived has a int value
struct Derived : Base<int> {};
template<template<typename> TT>
void do_stuff() {
TT<float> g;
std::cout << g.value;
}
do_stuff<Derived>(); // prints a int or a float?
您只能将模板类发送到模板模板参数。您必须将 JsonParser
设为模板:
template<typename T>
class JsonParser : MessageParser<T> {
public:
T Deserialize(const char *buf, size_t len) override { return 1; };
};
或者让你的类型接收一个普通类型:
template <typename Tparser>
class RpcServer{
public:
RpcServer(Tparser parser) : _parser(parser) {};
Tparser _parser;
};
要返回 Tmsg
,只需添加一个 typedef,或使用 decltype
:
template<typename Tmsg>
struct MessageParser {
using MsgType = Tmsg;
// ...
};
template <typename Tparser>
class RpcServer{
using Tmsg = typename Tparser::MsgType;
// or using decltype:
using Tmsg = decltype(std::declval<Tparser>().Deserialize("", 0));
public:
RpcServer(Tparser parser) : _parser(parser) {};
Tparser _parser;
};
我建议使用简单类型作为模板参数。