如何将可变参数模板的参数字段的参数包限制为特定类型

时间:2017-02-02 06:56:28

标签: c++ c++11 c++14 variadic-templates variadic-functions

这是这个原始问题的延续:Original Question更侧重于设计决策。如果可以做到这个问题,这个问题更多的是实际如何实施。

我目前的资料来源:

<input type="text" id="date" placeholder="Enter Date (YYYY-MM-DD)" />
<button id="btn">Get Day</button>

这将与一系列与以下原型相关的类一起使用:

template <typename ClassType,typename... Dimensions>
class DimensionPack {
public: 
    typename std::tuple<ClassType, std::tuple<Dimensions...> >::type Dim;
    const unsigned int numarguments = sizeof...(Dimensions);
};

我已经被问到为什么我不能使用template<typename ClassType, typename... Args> class MatrixReference; template<typename ClassType, typename... Args> class MatrixStorage; template<typename ClassType, typename... Args> class MatrixAllocation;

经过深思熟虑之后,我仍然倾向于使用带有辅助模板的可变参数包,将其存储到std::size_t...中以帮助打包和解压缩参数。此外,我需要测试这些参数在std::tuple的范围内,因此它们必须都是+整数。因此参数包本身或其内容可以是{x; x > 0}std::size_t,但它们都需要是一个或另一个。我还需要测试这些参数以检查它们的值是偶数还是奇数,并将这些结果保存到容器中。使用辅助函数将为我做到这一点。

知道这一点我倾向于使用参数包,这样我就可以轻松地将该包作为参考从一个模板传递到另一个模板,因为这些模板的集合可以一起工作,我也可以传递参数包到我的辅助函数来测试奇数和偶数值。

所以问题变成了:

  • unsigned int的参数包是否可以限制为特定类型,例如<typename... Args>std::size_t
  • 如果是这样,怎么办呢?
  • 如果没有,我有什么选择实现这个目标?

1 个答案:

答案 0 :(得分:2)

  

参数包是否可以限制为特定类型,例如std :: size_t或unsigned int?

布尔技巧以紧凑的方式做到了 作为一个最小的工作示例:

#include <type_traits>
#include <utility>

template<typename... Args>
constexpr bool check(Args&&...) {
    return std::is_same<
        std::integer_sequence<bool, true, (std::is_same<std::size_t, std::remove_reference_t<Args>>::value or std::is_same<unsigned int, std::remove_reference_t<Args>>::value)...>,
        std::integer_sequence<bool, (std::is_same<std::size_t, std::remove_reference_t<Args>>::value or std::is_same<unsigned int, std::remove_reference_t<Args>>::value)..., true>
    >::value;
}

int main() {
    static_assert(check(std::size_t{42}, 3u), "!");
    static_assert(not check(std::size_t{42}, 'c'), "!");
}

由于你的评论(强调我的),我在支票中使用了两种类型:

  

因此参数包本身或其内容可以是std :: size_t或unsigned int,但它们都需要是一个

wandbox上看到它正在运行。

请注意,您可以使用相同的技术静态检查用于初始化类的类型 举个例子:

template<typename... Args>
struct S {
    static_assert(std::is_same<
        std::integer_sequence<bool, true, (std::is_same<std::size_t, std::remove_reference_t<Args>>::value or std::is_same<unsigned int, std::remove_reference_t<Args>>::value)...>,
        std::integer_sequence<bool, (std::is_same<std::size_t, std::remove_reference_t<Args>>::value or std::is_same<unsigned int, std::remove_reference_t<Args>>::value)..., true>
    >::value, "!");
};

在这种情况下,这样的东西会编译:

S<std::size_t, unsigned int> s;

另一方面,以下内容将在编译时以错误结束:

S<std::size_t, char> s;