将"stored"可变参数模板类型解压缩为模板参数
Unpacking "stored" variadic template types into template parameters
我正在尝试编写模拟以用于单元测试。为此,我需要反映我无法更改的库的真实实现。这是一个非常简单的示例:
Library CodeIcantChange.h:
struct IFoo {};
struct IBar {};
template<typename... I>
struct implements {};
template<typename... I>
struct mocks {};
struct CRealSingle : implements<IFoo> {};
struct CRealMulti : implements<IFoo, IBar> {};
简单地说,我的模型就像:
#include "LibraryCodeICantChange.h"
struct CMockSingle : mocks<IFoo> {};
struct CMockMulti : mocks<IFoo, IBar> {};
但是,我想从真实的界面列表中推断出接口列表,而不是复制它。我可以在一个接口上使用它,但是我需要一组接口的模板参数。我将variadic类型存储到我称为 pack
的结构中,但我不知道如何解开这些类型:
#include "LibraryCodeICantChange.h"
template<typename... I>
struct pack {};
// just declared, not defined: only used for typing
template<typename... I>
pack<I...> steal_real_params(implements<I...>*);
template<typename C>
using steal_real_params_t = decltype(steal_real_params(std::declval<C*>()));
template<typename C>
struct MockBasedOnReal: mocks<steal_real_params_t<C>... /* how to unpack? */> {};
// error C3546: '...': there are no parameter packs available to expand
struct CMockSingle : MockBasedOnReal<CRealSingle> {}; // error while 'MockBasedOnReal<CRealSingle>' being compiled
struct CMockMulti : MockBasedOnReal<CRealMulti> {}; // error while 'MockBasedOnReal<CMockMulti>' being compiled
我想做的是可能的吗?如果是这样,如何?
因此,据我了解您的问题,它归结为此起点:
struct CRealMulti : implements<IFoo, IBar> {};
,您想拥有一个模板,可以将此CRealMulti
类送入其中,然后能够从mocks<Ifoo, IBar>
继承的内容。用GCC 7.1.1:
#include <utility>
struct IFoo {};
struct IBar {};
struct IBaz {};
template<typename... I>
struct implements {};
template<typename... I>
struct mocks {};
struct CRealSingle : implements<IFoo> {};
struct CRealMulti : implements<IFoo, IBar> {};
// Given a subclass of implements<I...>, extract it:
template<typename ...I>
implements<I...> return_implements(implements<I...> &&);
// Specialization to extract the parameter pack:
template<typename T> struct implements_to_mocks;
template<typename ...I>
struct implements_to_mocks<implements<I...>> {
typedef mocks<I...> mocks_t;
};
// All the hard work is here:
template<typename C> struct to_mock {
typedef decltype(return_implements(std::declval<C &&>())) implements_t;
typedef typename implements_to_mocks<implements_t>::mocks_t type;
};
// to_mock_t provides a convenient shortcut
template<typename T>
using to_mock_t=typename to_mock<T>::type;
// The end result:
//
// to_mock_t<CRealMulti> is an alias for mocks<IFoo, IBar>, ready
// and waiting to be inherited from.
void foo()
{
typedef std::enable_if<std::is_same<
to_mock_t<CRealMulti>, mocks<IFoo, IBar>>::value>::type t;
}
相关文章:
- 扩展C++生成的代码的模板参数类型名称
- 如何在 c++ 中定义接受不同参数类型的函数向量?
- 在 C++ 中运行时调用模板时,是否可以切换模板的参数类型?
- 将函数参数类型声明为 auto
- 将函数的参数 - 签名从使用 'std::function<T>' 转换为模板参数类型
- 在 C++17 中调用具有不同参数类型的构造函数
- 具有先前参数类型匹配的参数包
- 我想知道为什么"std::unique_ptr<int> foo(新 int)"是合法的,因为"std::<int>unique_ptr"要求输入参数类型应该是"int"?
- 将可变参数类型列表的扩展打包为复杂类型的初始值设定项列表 - 合法吗?
- MSVC 错误:4 个重载中的任何一个都无法转换所有参数类型
- 使用constexpr + auto作为返回和参数类型的奇怪类型推导
- 如何从第一个参数推断第二个参数类型?
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 如何用不同的参数类型和数字回调函数
- C++stoi:这两个重载都无法转换所有参数类型
- 为什么std::{container}::template不能推导其参数类型
- 为模板参数类型中的新对象分配内存
- 为指向成员模板参数的指针推导额外模板参数类型的紧凑方式
- 使用std::conditional中的模板来确定函数参数类型
- C++中的短参数类型