使类期望单个模板参数的模板模板参数接受可变参数模板参数的模板模板参数?

时间:2019-07-13 04:05:09

标签: c++ templates c++14 variadic-templates template-templates

我正在尝试写类似于std::bind的东西,但是写的是模板类型而不是对象。实际上,我想将一个模板参数绑定到模板类型。 (以类似的方式,在std::bind中,我们将一个(或多个)实参绑定到一个函数式对象。)

下面的C ++代码可以最好地说明我想要的东西:

#include <tuple>
#include <type_traits>

using namespace std;

/* This struct should be in some header-only utility library */
template <template <typename...> typename Template, typename T>
struct template_bind {
    template <typename... Args>
    using template_type = Template<T, Args...>;
};


/* This class should be in a separate header file */
// If we change the following line to add '...' then it works
// template <template <typename...> typename Template>
template <template <typename> typename Template>
class my_complicated_class {
public:
    /* stuff */
private:
    Template<float> data_;
};

/* This probably would be in a third file that includes both headers */
int main()
{
    using t1 = template_bind<std::tuple, int>;
    using t2 = template_bind<t1::template_type, double>;
    my_complicated_class<t2::template_type> stuff_with_tuple; // Compile error

    using p1 = template_bind<std::pair, int>;
    my_complicated_class<p1::template_type> stuff_with_pair; // Compile error
}

有趣的是,该代码在C ++ 17的GCC和MSVC上编译,但是在Clang(使用任何C ++标准的Clang)或GCC / MSVC的C ++ 14上编译。错误(在那些不会编译的编译器上)是my_complicated_class需要一个模板模板参数,该参数需要一个单个模板参数,而template_type是一个可变模板。

更改my_complicated_class以接受可变参数模板模板参数可解决所有编译器上的问题。但是,将my_complicated_class更改为接受可变参数模板模板参数会感到很奇怪,因为my_complicated_class可能对所使用的模板模板参数一无所知。 (否则,可能会争论所有模板模板参数都应写为可变参数模板,例如template <template <typename...> typename Template>,但这似乎不是通常写模板模板参数的方式。)

哪个编译器不符合要求,如何使代码在C ++ 14编译器上编译?

1 个答案:

答案 0 :(得分:1)

Clang不支持C ++ 17模板模板参数/参数匹配。

相关段落:

  

当模板参数的相应类模板或别名模板(称为A)的template-parameter-list中的每个模板参数与相应的模板参数匹配时,模板参数与模板模板参数(称为P)匹配P的template-parameter-list中的template参数。[...]

  

当P至少与模板参数A一样专门化时,模板参数与模板模板参数P匹配。[...]

这是最后一句话,使您的代码在C ++ 17中格式正确。当P为template<class> class且A为template<class...> class时,P比A更专业。

相关问题