【问题标题】:Variadic template of variadic template class可变参数模板类的可变参数模板
【发布时间】:2014-08-21 01:24:13
【问题描述】:

我正在尝试创建一个名为 Choose 的函数,它可以将以下内容作为参数:

template<typename... Args>
class Option
{
    Option(Args... arguments)
    {
        // irrelevant
    }
    // ...
}

void Foo()
{
    Choose(
         Option<int, int>(3, 5),
         Option<int>(7,123),
         Option<int, int, int, int>(1, 2, 3, 4)
    );
}

所以我有一个可变参数类型的类,我想创建一个函数,该函数接受该类的任意数量的实例,其中每个实例的类型都可以有 different 参数。

我能够创建这样一个函数,其中所有实例的类型都需要具有相同的参数:

template <template <typename... Args> class... Opt, typename... Args>
void Choose(EnemyAIState& state, Opt<Args...>... option)
{
    // irrelevant
}

void Foo()
{
    Choose(state,
        Option<int>(1),
        Option<int>(2),
        Option<int>(3)
    );
}

但是,我无法实现我的最终目标,因为我找不到合适的 syntax 来使用。我希望你能在正确的方向上帮助我。

【问题讨论】:

  • 你总是可以把它们当作简单的template&lt;typename...Opt&gt; void Choose(EnemyAIState&amp; state, Opt... option)
  • 哦哇哈哈,新鲜的想法总是更好。现在它可以工作了,我仍然对这是否可能感兴趣。
  • 我的意思是我开始的方式。
  • 我认为这不可能。如果您想要更好的错误消息,请使用static_assert
  • @AartStuurman:答案不包含在问题中。如果您的“答案”与 T.C. 的答案不同,请将其作为新答案发布在此页面上。

标签: c++ templates variadic


【解决方案1】:

我认为你不能直接做你想做的事——你需要像“一包包”这样的东西,而没有这样的东西。

如果您想要更好的错误消息,请编写一个static_assert 来测试传入的每个类型是Option

// helper template that checks all of values are true
template<bool... values>
struct all_true;

template<>
struct all_true<> : std::true_type { };

template<bool b, bool...values>
struct all_true<b, values...> : std::integral_constant<bool, b && all_true<values...>::value> { };

template<typename... Args>
struct Option
{
    Option(Args... /*arguments*/)
    {
        // irrelevant
    }
    // ...
};

// trait class that tests that a type is an Option
template<typename T>
struct is_option : std::false_type { };

template<typename... Args>
struct is_option<Option<Args...>> : std::true_type { };

template <typename... Opt>
void Choose(Opt... arguments)
{
    // check that each type is an Option
    static_assert(all_true<is_option<Opt>::value...>::value, "Arguments must all be Options");
    // irrelevant
}

Demo.

【讨论】:

  • 这很酷。我根本不知道 C++ 中的断言。非常感谢,这给出了一些明确的信息。
  • 以下链接提供了您的 is_option 函数的通用版本,可能对阅读此问题的人有用:stackoverflow.com/questions/17390605/…
【解决方案2】:

如果一次处理一个参数,标准的可变参数模板解决方案效果很好:

void Choose()
{
    //do nothing, end of list
}

template <typename... Args, class... Rest>
void Choose(const Option<Args...>& option, Rest&&... rest)
{
    //irrelevant

    Choose(std::forward<Rest>(rest)...);
}

它给出的错误消息与您在其他方式中得到的相同,只是调用堆栈大小更吓人。这就是我见过的大多数可变参数模板函数的工作方式:准递归。

http://ideone.com/XuWSSx

【讨论】:

    猜你喜欢
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2013-09-14
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多