【问题标题】:std::tuple as template argument?std::tuple 作为模板参数?
【发布时间】:2015-05-04 22:07:37
【问题描述】:

我正在尝试编写一个std::sort 模板比较类,它应该接收未知数量的元组(可变参数模板)。每个元组应该由一个列(我们的代码中的某种类型)和一个 bool 组成,指定该列是按升序还是降序排序。

基本上,我想要类似的东西:

// doesn't compile - conceptual code
template <typename std::tuple<Col, bool>>
struct Comparator
{
    bool operator() (int lhs, int rhs)
    {
         // lhs and rhs are row indices. Depending on the columns
         // and the bools received, decide which index should come first
    } 
}

这种事情在 C++ 11 中可能吗?

【问题讨论】:

  • @BaummitAugen 因为稍后我想根据列类型添加模板专业化(应该提到)
  • 不应该operator() 采取tuple&lt;&gt; 吗?这只能用于对整数进行排序...
  • @Barry 它对整数进行排序,但相对于作为模板参数传递的列(整数表示行索引,列表示要排序的列)
  • 我不知道“关于列”是什么意思。你能举个例子吗?

标签: c++ templates c++11


【解决方案1】:

是的,有可能 - 您想要 Comparator 的部分专业化:

template <typename T>
struct Comparator;

template <typename Col>
struct Comparator<std::tuple<Col, bool>>
{
    // ...
};

【讨论】:

    【解决方案2】:

    这可能吗?是的,但你需要一些相当丑陋的模板技巧。

    //a trait for checking if a type is of the form std::tuple<T,bool>
    template <class Tuple>
    struct is_col_bool_tuple : false_type{};
    
    template <typename Col>
    struct is_col_bool_tuple<std::tuple<Col,bool>> : true_type{};
    
    //a helper struct for checking if all the values in a boolean pack are true
    template<bool...> struct bool_pack;
    template<bool... bs> 
    using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
    
    //a trait to check if a list of types are all of the form std::tuple<T,bool>
    template <class... Tuples>
    using are_col_bool_tuples = all_true<is_col_bool_tuple<Tuples>::value...>;
    
    //an incomplete type for when we pass incorrect template arguments
    //this impl helper is needed because variadic parameters need to be last
    template <typename Enable, class... Tuples>
    struct ComparatorImpl;
    
    //our specialized implementation for when the template arguments are correct
    template <class... Tuples>
    struct ComparatorImpl<std::enable_if_t<are_col_bool_tuples<Tuples...>::value>,
                          Tuples...>
    {
         bool operator() (int lhs, int rhs)
        {
             //do your comparison
        } 
    };
    
    //a nice alias template for forwarding our types to the SFINAE-checked class template
    template <class... Tuples>
    using Comparator = ComparatorImpl<void, Tuples...>;
    

    【讨论】:

    • 投反对票的人能解释一下这有什么问题吗?也许我误解了这个问题?
    猜你喜欢
    • 2012-12-11
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2020-04-07
    • 2014-01-03
    • 2014-08-31
    • 2013-06-14
    • 1970-01-01
    相关资源
    最近更新 更多