gpt4 book ai didi

c++ - 动态构建模板参数包

转载 作者:太空狗 更新时间:2023-10-29 23:23:54 26 4
gpt4 key购买 nike

我试图让我的代码调用一个类列表的方法,我希望能够在编译时配置这个列表。为了让事情更清楚(我希望),这大约是我目前正在做的事情:

template <class...> class pack {};

class A {
public:
static void foo() {};
};
class B {
public:
static void foo() {};
};
class C {
public:
static void foo() {};
};

using ClassList = pack<A, B, C>;

template<class T, class ...Remaining>
void do_something(pack<T, Remaining...>) {
// do something with T
T::foo();
do_something(pack<Remaining...>());
}

void do_something(pack<>) {
// do nothing, recursion ends
}

int main() {
do_something(ClassList());
}

基本上,它调用 do_something() 将 A、B 和 C 中的每一个作为模板参数 T。

这是一个转折点:我希望能够根据“#ifdef”动态启用或禁用 A、B 和 C。我显然可以使用类似的东西

#if defined(USE_A) && defined (USE_B) && defined (USE_C)
using ClassList = pack<A, B, C>;
#elif defined(USE_A) && defined (USE_B)
using ClassList = pack<A, B>;

但这会导致 2^n 个语句(如果 n 是潜在类别的数量)。

我的解决方案尝试

我的解决方案尝试是为每个我想添加到类列表中的类 T 派生自 pack 的“AddT”类,在其模板定义中匹配 pack 类“内部”的参数包,然后添加 T. 类似以下内容:

using BaseClassList = pack<A, B>;

#ifdef USE_C

template <template <class ...Others> class oldpack>
class AddC : public pack<C, Others...> {};
using ClassesWithC = AddC<BaseClassList>;

#else

using ClassesWithC = BaseClassList;

#endif

但是,看起来在定义 AddC 时无法访问“内部”模板参数(包)“其他”,我得到的错误是:

error: 'Others' was not declared in this scope

我是不是在做一些完全愚蠢的事情?有更好的方法吗?或者可以解决上面的问题吗?如果有任何帮助,我会很乐意使用 C++14(甚至 C++1z,只要它是由合理版本的 GCC 和 clang 实现的)。

最佳答案

利用 C++ 的空白灵 active 并分别检查每一个。

template<class, class...Ts>
using pack_helper = pack<Ts...>;

using ClassList = pack_helper<void
#ifdef USE_A
,A
#endif
#ifdef USE_B
,B
#endif
#ifdef USE_C
,C
#endif
>;

pack_helper丢弃它的第一个类型,然后生成一个 pack与其余的。我们通过void

我们这样做是为了让每个其他包元素都可以以逗号开头,包括第一个。


但这并没有想象中的那么有趣。

template<class...>struct pack{using type=pack; constexpr pack(){}};
template<class...Ts>constexpr pack<Ts...> pack_v{};

template<class...Ts, class...Us>
constexpr pack<Ts...,Us...>
operator+( pack<Ts...>, pack<Us...> )
{ return {}; }

constexpr auto Classes = pack_v<>
#ifdef USE_A
+pack_v<A>
#endif
#ifdef USE_B
+pack_v<B>
#endif
#ifdef USE_C
+pack_v<C>
#endif
;
using ClassList = decltype(Classes);

我们将类型包加在一起以获得答案。

在 C++11 中,替换 pack_v<?>pack<?>{} .

关于c++ - 动态构建模板参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44674563/

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