用于默认模板参数的参数包

时间:2017-07-28 13:52:16

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

我想做这样的事情:

function objectsFunctionallyIdentical(a, b) {
    //If they are the same object
    if (a == b) {
        return true;
    }
    //get keys
    var keysA = Object.keys(a);
    var keysB = Object.keys(b);
    //If not the same amount of keys, return false
    if (keysA.length != keysB.length) {
        return false;
    }
    //get unique keys
    var uniqueKeys = keysA
        .concat(keysB)
        .filter(function (value, index, arr) {
        return (arr.indexOf(value) == index);
    });
    //By key loop
    for (var keyIndex = 0; keyIndex < uniqueKeys.length; keyIndex++) {
        var key = uniqueKeys[keyIndex];
        //If key undefined, return false
        if (a[key] == void 0 || b[key] == void 0) {
            return false;
        }
        //If key inheritance differs, return false
        if (a.hasOwnProperty(key) != b.hasOwnProperty(key)) {
            return false;
        }
        //If key mismatch, return false
        if (a[key] != b[key]) {
            return false;
        }
    }
    //All tests passed, return true
    return true;
}
function listOfObjectsFunctionallyIdentical(lista, listb) {
    //list of suspects
    var mistMatches = [];
    //loop list a
    for (var index = 0; index < lista.length; index++) {
        var objA = lista[index];
        //check for occurrence in list b
        if (listb.some(function (objB) {
            return objectsFunctionallyIdentical(objB, objA);
        })) {
            continue;
        }
        //add to mismatches if no occurrence in list b
        mistMatches.push(objA);
    }
    //loop list b
    for (var index = 0; index < listb.length; index++) {
        var objB = listb[index];
        //check for occurrence in list a
        if (lista.some(function (objA) {
            return objectsFunctionallyIdentical(objB, objA);
        })) {
            continue;
        }
        //add to mismatches if no occurrence in list a
        mistMatches.push(objB);
    }
    return mistMatches;
}
//TEST
var obja = { person1ID: 1, person2ID: 20, value: "test" };
var objb = { person1ID: 2, person2ID: 20, value: "test" };
var objc = { person1ID: 3, person2ID: 20, value: "test" };
var objd = { person1ID: 4, person2ID: 20, value: "test" };
var obje = { person1ID: 1, person2ID: 20, value: "test" };
var arr1 = [obja, objb];
var arr2 = [obja, objb, objc];
var arr3 = [obja, objb, objd];
console.log(objectsFunctionallyIdentical(obja, obja)); //TRUE, they are the same
console.log(objectsFunctionallyIdentical(obja, objb)); //FALSE, they are different
console.log(objectsFunctionallyIdentical(obja, obje)); //TRUE, they are alike
console.log(listOfObjectsFunctionallyIdentical(arr1, arr2)); //1 mismatch (objc)
console.log(listOfObjectsFunctionallyIdentical(arr2, arr2)); //0 mismatch
console.log(listOfObjectsFunctionallyIdentical(arr2, arr3)); //2 mismatch (objc,objd)

我知道参数包应该只出现在最后,但我记得有一些例外。你认为有没有办法使这个代码(或类似的东西)起作用?

由于

1 个答案:

答案 0 :(得分:3)

一种方式:

  • 将类型包装成元组。

  • 使用专门化将类型列表转换为类型

#include <tuple>
#include <utility>

template<int...myints> struct A {};

namespace detail {
    template<class Sequence>
    struct make_A_from;

    template<class T, T...ts>
    struct make_A_from<std::integer_sequence<T, ts...>> {
        using type = A<ts...>;
    };
}
template<class Sequence> using make_A_from = typename detail::make_A_from<Sequence>::type;

template<class Sequence, class TraitsTuple = make_A_from<Sequence> >
struct B;

template<typename Int, Int...myints, class Traits> 
struct B<std::integer_sequence<Int, myints...>, Traits>
{
    using ints_tuple = std::tuple<std::integral_constant<Int, myints>...>;
    using traits_type = Traits;
};

namespace detail {
    template<typename Int, Int...is>
    struct make_B
    {
        using type = B<std::integer_sequence<Int, is...>>;
    };
}

template<int...is> using make_B = B<std::integer_sequence<int, is...>>;

int main()
{
    make_B<1,3,4,5> b;
    B<std::integer_sequence<int, 5,6,7,8>> b2;
    B<std::integer_sequence<int, 5,6,7,8>, class CustomTrait> b3;
}