代码之家  ›  专栏  ›  技术社区  ›  cmannett85

与Boost.Mp11抗争:“需要一个类模板,但得到了'T'”

  •  3
  • cmannett85  · 技术社区  · 7 年前

    我正试着检查一下房间

    #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 回复  |  直到 7 年前
        1
  •  1
  •   llonesmiz    7 年前

    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;
    }
    
        2
  •  3
  •   StoryTeller - Unslander Monica    7 年前

    直接的错误是。。。

    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 不会获取它所期望的谓词类型。恐怕我对这个库不太熟悉,无法告诉您如何获得除此之外的工作版本。