gpt4 book ai didi

c++ - 将 "stored"可变模板类型解包到模板参数中

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:08:20 25 4
gpt4 key购买 nike

我正在尝试编写用于单元测试的模拟。为此,我需要镜像我无法更改的库的真实实现。这是一个非常简单的例子:

库代码ICantChange.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> {};

但是,我想从真实的接口(interface)列表中推断出来,而不是复制它。我让它适用于单个接口(interface),但我需要接口(interface)的一组可变模板参数。我将可变参数类型存储到一个名为 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++ - 将 "stored"可变模板类型解包到模板参数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46084147/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com