如何让期望单个模板参数的模板模板参数的类接受可变模板参数的模板模板参数?

3
我希望能够写出类似于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++标准)或C++14的GCC / MSVC上无法编译。这些不支持编译的编译器出现错误,即my_complicated_class需要一个模板模板参数,该参数接收单个模板参数,但template_type是一个可变模板参数。
my_complicated_class更改为接受可变模板模板参数可以解决所有编译器上的问题。但是,更改my_complicated_class以接受可变模板模板参数可能会感觉很奇怪,因为my_complicated_class可能不应了解使用的模板模板参数。 (否则,可以认为所有模板模板参数都应编写为可变模板,例如template <template <typename...> typename Template>,但似乎并不是通常编写模板模板参数的方式。)
哪个编译器不符合规范?如何使此代码在C++14编译器上编译?
1个回答

3

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

相关段落:

当模板参数列表中的每个模板参数在相应类模板或别名模板 A 的模板参数列表中与 P 的模板参数列表中的相应模板参数匹配时,模板参数与模板模板参数(称其为 P)匹配。[...]

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

这是C++17中使您的代码符合规范的最后一个句子。 当P为template<class> class且A为template<class...> class时,P比A更为专业。


有没有办法在C++14编译器上实现类似的功能? - Bernard
@Bernard,有很多解决方法。可接受的解决方案取决于您在代码中准备更改什么。为什么不按照您在代码注释中所说的定义my_complicated_classtemplate<template<class...>class> class my_complicated_class - Oliv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接