与Boost.Mp11苦苦挣扎:“期望一个类模板,得到了'T'”

时间:2018-11-27 08:05:01

标签: c++ boost boost-mp11

我正在尝试使用Boost.Mp11检查特殊类型元组的 unspecialized 唯一性:

#include <iostream>
#include <vector>
#include <deque>
#include <tuple>

#include <boost/mp11/algorithm.hpp>

namespace
{
template <typename T, template <typename...> typename U>
struct is_specialisation : std::false_type {};

template <template <typename...> typename U, typename... Args>
struct is_specialisation<U<Args...>, U> : std::true_type {};

template <template <typename...> typename U>
struct is_specialisation_meta
{
    template <typename T>
    using type = is_specialisation<T, U>;
};

template <typename TypeList>
struct unique_specialisation
{
    template <typename T>
    using type = std::is_same<
        boost::mp11::mp_count_if<
            TypeList,
            is_specialisation_meta<T>::template type // Error!
        >,
        boost::mp11::mp_size_t<1>
    >;
};
}

int main()
{
    using types = std::tuple<
        std::vector<int>,
        std::deque<int>,
        std::tuple<int>
    >;

    using all_unique_specialisations = boost::mp11::mp_all_of<
        types,
        unique_specialisation<types>::template type
    >;

    std::cout << std::boolalpha << all_unique_specialisations::value << std::endl;

    return EXIT_SUCCESS;
}

您可以在Coliru上运行以上代码。对于每种类型,遍历整个列表都是为了尝试找到非专业的等效项,因此{std::vector<int>, std::deque<float>, std::tuple<Foo>}会通过,而{std::vector<int>, std::vector<float>, std::tuple<Foo>}不会。

但是我收到此错误:

main.cpp:30:37: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class ...> class U> struct {anonymous}::is_specialisation_meta'
             is_specialisation_meta<T>::template type
                                     ^
main.cpp:30:37: note:   expected a class template, got 'T'

但是我不知道T是如何未知的-有人可以看到我在做什么吗?

2 个答案:

答案 0 :(得分:3)

立即出现错误...

template <typename T>
using type = std::is_same<
    boost::mp11::mp_count_if<
        TypeList,
        is_specialisation_meta<T>::template type // Error!
    >,
    boost::mp11::mp_size_t<1>
>;

如果我们将其与...进行比较

template <template <typename...> typename U>
struct is_specialisation_meta

...我们看到代码传递了一个类型名称T,其中应该使用模板U。但是进行修改只会将错误转移到其他地方,因为现在boost.mp不会获得期望的谓词类型。恐怕我不太熟悉该库,无法告诉您如何获得除此以外的可用版本。

答案 1 :(得分:1)

Running on Wandbox

#include <iostream>
#include <vector>
#include <deque>
#include <tuple>

#include <boost/mp11/algorithm.hpp>

namespace
{
template <typename T, template <typename...> typename U>
struct is_specialisation : std::false_type {};

template <template <typename...> typename U, typename... Args>
struct is_specialisation<U<Args...>, U> : std::true_type {};

template <typename T> struct is_specialisation_meta;//ADDED

template <template <typename... > typename U, typename... Args>//CHANGED
struct is_specialisation_meta<U<Args...>>
{
    template <typename T>
    using type = is_specialisation<T, U>;
};

template <typename TypeList>
struct unique_specialisation
{
    template <typename T>
    using type = std::is_same<
        boost::mp11::mp_count_if<
            TypeList,
            is_specialisation_meta<T>::template type // Error!
        >,
        boost::mp11::mp_size_t<1>
    >;
};
}

int main()
{
    using types = std::tuple<
        std::vector<int>,
        std::deque<int>,
        std::tuple<int>
    >;

    using types2 = std::tuple<
        std::vector<int>,
        std::vector<float>,
        std::tuple<int>
    >;

    using all_unique_specialisations = boost::mp11::mp_all_of<
        types,
        unique_specialisation<types>::template type
    >;

    using all_unique_specialisations2 = boost::mp11::mp_all_of<
        types2,
        unique_specialisation<types2>::template type
    >;

    std::cout << std::boolalpha << all_unique_specialisations::value << std::endl;
    std::cout << std::boolalpha << all_unique_specialisations2::value << std::endl;

    return EXIT_SUCCESS;
}