gpt4 book ai didi

c++ - 具有交替类型的参数包

转载 作者:可可西里 更新时间:2023-11-01 16:36:05 26 4
gpt4 key购买 nike

我有一个 struct C,它使用可变数量的 struct Astruct B 实例进行初始化。例如:

struct A
{};

struct B
{};

struct C
{
C(A&& o1, B&& p1, A&& o2)
{}
C(A&& o1, B&& p1, A&& o2, B&& p2, A&& o3)
{}
C(A&& o1, B&& p1, A&& o2, B&& p2, A&& o3, B&& p3, A&& o4)
{}
C(A&& o1, B&& p1, A&& o2, B&& p2, A&& o3, B&& p3, A&& o4, B&&p4, A&& o5)
{}
};

因此,与其提供具有不同数量参数的多个构造函数,我更想找到一些通用的东西。但是,ctor 参数的数量总是在两个参数左右增长:B&&A&&。这可以使用参数包来完成吗?或者是另一种解决方案,而不是为每个参数数量实现一个相应的 ctor?

目标应该是 struct C 可以像下面的例子那样构造:

C c1 = { A(), B(), A() };
C c2 = { A(), B(), A(), B(), A(), B(), A() };

等等

最佳答案

您可以使用可变参数模板和 SFINAE 仅启用类型参数满足您(或任意)条件的构造函数。

#include <type_traits>
struct A {};
struct B {};

你需要type_traits对于 std::false_typestd::true_type .

alternates模板是关键。目标是制作alternates<X, Y, T1, T2, T3, ..., Tn>继承自 std::true_type当且仅当T1 , ... Tn列表是交替的 XY .默认选择(就在下方)是,但我们专注于匹配案例。

template <typename X, typename Y, typename... Ts>
struct alternates : std::false_type {};

我选择使此模板比您在这里的要求更通用,并允许 alternates<X, Y>true_type 继承.空列表满足其所有元素交替出现的数学要求。这将是下面递归定义的一个很好的权宜之计。

template <typename X, typename Y>
struct alternates<X, Y> : std::true_type {};

alternates<X, Y, Ts...> 的任何其他列表当且仅当 Ts... 交替出现减去第一个元素交替 YX (Y 第一个!)。

template <typename X, typename Y, typename... Ts>
struct alternates<X, Y, X, Ts...>
: alternates<Y, X, Ts...> {};

struct C
{

我们将构造函数定义为一个模板,它首先接受一个参数包(类型将被推导,调用时无需指定)并且它有一个用于 SFINAE 目的的默认模板参数。如果无法根据参数包计算出默认参数,则构造函数将不存在。我添加了关于我从示例中假设的对数的额外条件。

    template<typename... Ts,
typename = typename std::enable_if<
sizeof...(Ts) % 2 == 1 &&
sizeof...(Ts) >= 3 && // did you imply this?
alternates<A, B, Ts...>::value
>::type>
C(Ts&&...);
};

方式SFINAE作品是std::enable_if只定义了 std::enable_if<condition, T>::type (::type 部分)如果condition是真的。这可以是在编译​​时可计算的任意 bool 表达式。如果是假的,说::type最后将是 替换失败 并且您尝试使用它的重载(例如 C{A(), A(), A()} )将不会被定义。

您可以测试以下示例是否按预期工作。注释掉的那些预计不会起作用。

int main() {
C c1 { A(), B(), A() };
C c2 { A(), B(), A(), B(), A(), B(), A() };
// C c3 {}; // I assumed you need at least 2
// C c4 { A(), B(), A(), A() }; // A, A doesn't alternate
// C c5 { B(), A(), B() }; // B, A, B not allowed
// C c6 { A(), B(), A(), B() }; // A, B, A, B doesn't pair
}

Try the code here.

关于c++ - 具有交替类型的参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53729854/

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