【发布时间】:2020-01-17 12:25:02
【问题描述】:
我想采用一个定义良好的模板类,它依赖于 boost::signals2 并将其抽象为更深的通用层,这可以消除依赖关系,允许使用不同的实现,但仍然允许使用更高级别的函数取决于更通用的接口而不是更具体的接口来使用。在我的重构中,我完全被卡住了。而且,我已经知道我在这里有点不合群。今年我才开始真正学习 C++。但是,这有点有趣。但是我对模板的理解缺少一些东西。首先,我正在开发的库将使用 C++17,我使用 clang++ (Mac),并且依赖于 Boost ~1.7.2 Signals2。
考虑以下摘录:
#include <boost/signals2.hpp>
template<typename Functional_T, typename Return_T, typename ...Args_T>
using SignalHandler = typename Functional_T::template Functional_T<Return_T(Args_T...)>;
template<typename Connection_T>
struct SignalConnection; //no issues here, just wraps a private Connection_T with a getter/setter
template<typename Connection_T, typename Functional_T, typename Return_T, typename ...Args_T>
struct ISignalEmitter
{
protected:
virtual Return_T trigger(Args_T ...args) = 0;
public:
virtual void disconnectAll() = 0;
virtual SignalConnection<Connection_T> onSignal(SignalHandler<Functional_T, Return_T, Args_T...> &signalHandler) = 0;
virtual void cancelOnSignal(const SignalConnection<Connection_T> &connection) = 0;
};
但这就是我完全陷入困境的地方。我想定义的东西,在我的脑海里是这样的:
template<typename Return_T, typename ...Args_T>
using BoostSignals2SignalHandler = SignalHandler<boost::signals2::slot, Return_T, Args_T...>;
而且我想我们都知道会发生什么。 slot 需要模板参数。那么我该如何构建它以使其工作呢?我尝试了各种各样的东西,但我被卡住了。我的下一个猜测是:
template<typename Return_T, typename ...Args_T>
using BoostSignals2SignalHandler = SignalHandler<template boost::signals2::slot::template, Return_T, Args_T...>;
我不想问,但我知道我不能成为第一个试图解开这个谜题的人。并且必须有一种方法以一种易于理解的方式来考虑这些模板,而不仅仅是猜测和测试。我有一个模板别名BoostSignals2SignalHandler,它是SignalHandler 的特定版本减去第一个模板参数,加上使用现有模板作为更通用模板的特定模板参数。
我会问,“这是糟糕的设计吗?”但我觉得这个概念足以解决我想要解决的问题。我只是不明白该怎么做。谁能指出我正确的方向?再说一次,我不想问。搞清楚这个就很头疼了。提前致谢!
【问题讨论】:
-
所以您希望您的模板别名
SignalHandler将模板作为其第一个参数?你知道template template parameters吗? -
我找到了关于模板模板参数的信息,并且我尝试了几个我不明白的咒语,当我把它们敲出来的时候。老实说,这似乎是一种黑魔法资源,而不是我真正了解如何使用的东西。
标签: c++ templates variadic-templates type-alias