首页 > 解决方案 > 模板模板、可变参数模板和推导指南:编译器错误?

问题描述

考虑以下大量模板化的代码:

// Preamble
#include <list>
#include <deque>
#include <vector>
#include <iostream>
#include <type_traits>

// Rebind template template type traits
template <class> struct rebind_template_template;
template <template <class...> class Template, class... Types>
struct rebind_template_template<Template<Types...>> {
    template <class... Args>
    using type = Template<Args...>;
};

// Rebind template parameters type traits
template <class> struct rebind_template_parameters;
template <template <class...> class Template, class... Types>
struct rebind_template_parameters<Template<Types...>> {
    template <template <class...> class Arg>
    using type = Arg<Types...>;
};

// Template pack
template <template <class...> class... Templates>
class template_pack
{
    private:
    template <class... Args>
    using if_constructible_t = std::void_t<
        typename rebind_template_parameters<Args>::template type<Templates>...
    >;

    public:
    template <class... Args, class = if_constructible_t<Args...>>
    constexpr template_pack(const Args&...) noexcept {}
};

// Class template argument deduction guide
template <class... Args>
template_pack(const Args&...) -> template_pack<
    rebind_template_template<Args>::template type...
>;

// Pretty-printing
template <class Arg>
void print() {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

// Main
int main(int argc, char* argv[])
{
    template_pack pack(std::list<int>{}, std::deque<int>{}, std::vector<int>{});
    print<decltype(pack)>();
    return 0;
}

它的作用是从它的参数中推导出一组模板模板。它适用于gcc 8and 9,但不适用于clang。但我不知道这是否是有效的 C++。无所谓,因为它起作用gcc但不起作用clang,一个是对的,另一个不是。哪一个是对的?

返回的错误clang是:

error: pack expansion contains parameter pack 'Args' 
that has a different length (3 vs. 1) from outer parameter packs

注意:欢迎任何可以重现问题的更简单的代码。

标签: c++c++17template-argument-deductioncompiler-bugtemplate-templates

解决方案


推荐阅读