【问题标题】:For every template type an argument of a set type对于每个模板类型,一个集合类型的参数
【发布时间】:2017-02-22 05:39:08
【问题描述】:

假设我有一个可变参数模板类。如何创建一个函数,使其参数为集合类型,例如int,参数的数量等于模板类型的数量?

template <typename... Types>
class Test
{
public:
    void Func(???); // I don't know how to declare such a function
}

Test<string, bool, long> myTest; // Three types
myTest.Func(905, 36, 123315); // Three arguments, but always of type int.

最后,函数的目标是返回一个由所提供的整数组成的元组。为简单起见,我在示例代码中显示该函数为 void。

【问题讨论】:

  • This 和额外的sizeof...check?
  • 喜欢这个? ideone.com/PASclP
  • 这里甚至不需要Types,因为参数包的大小可以通过调用来推断:ideone.com/tPe6Tj
  • @Simon Kraemer 我希望 Func 的参数数量等于类模板类型的数量。此外,我想强制它们始终为整数。
  • @Gill Bates 这已经非常接近了。接下来对我来说:如何让返回类型 std::tuple 包含等于类型数量的整数?

标签: c++ c++11 templates constructor variadic-templates


【解决方案1】:
template <typename... Types>
class Test
{
    template <typename>
    using int_t = int;

public:    
    void Func(int_t<Types>... ints)
    {
    }
};

DEMO

【讨论】:

  • 聪明!我喜欢这个解决方案。
  • 请注意,您的解决方案允许隐式转换 - 不确定这是否是 OP 想要的。
  • 您能否详细说明这是如何工作的?我从来没有见过一个模板和使用组合。
  • @AartStuurman 它是一个别名模板,其设计方式使得无论您指定为类型模板参数,例如T,然后int_t&lt;T&gt; 将始终被int 替换。未使用的类型模板参数用于利用包扩展并生成函数参数列表
【解决方案2】:

wandbox example - (适用于 C++11)


如果您不需要 SFINAE,可以使用static_assert 确保满足您的条件:

template <typename... Types>
class Test
{
public:
    template <typename... Ts>
    void Func(Ts...)
    {
        static_assert(sizeof...(Ts) == sizeof...(Types), "");
        static_assert(std::conjunction<std::is_same<Ts, int>...>{}, "");
    }
};

(如果您需要 SFINAE,请使用std::enable_if。)

std::conjunction 检查传递给它的所有条件是否为真。


对于上面的例子,以下调用是有效/无效的:

myTest.Func(905, 36, 123315); // valid
myTest.Func(905, 36, 123315.f); // invalid
myTest.Func(905, 22); // invalid

如您所见,此解决方案不允许隐式转换。如果您希望它们被允许,您可以使用 std::is_convertible 而不是 std::is_same

【讨论】:

  • 加上conjunction是C++17,有风险有风险。
  • @GillBates:很容易实现,请看我的魔杖盒示例。它适用于 C++11。
  • 我同意您的解决方案完全解决了我的问题。但是,在我看来,Piotr Skotnicki 的解决方案似乎更容易阅读,并且(对我而言)更容易扩展到其他类似用途。因此,我选择他的答案作为最佳答案,尽管你的答案也对我有很大帮助。
  • 不客气。我同意,Piotr 的解决方案肯定更好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多