【问题标题】:Make class expecting a template template parameter of single template parameter accept a template template parameter of variadic template parameter?使期望单个模板参数的模板模板参数的类接受可变参数模板参数的模板模板参数?
【发布时间】:2019-11-22 18:09:57
【问题描述】:

我正在尝试编写类似于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
}

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

my_complicated_class 更改为接受可变参数模板模板参数可以解决所有编译器上的问题。但是,将my_complicated_class 更改为接受可变参数模板模板参数会感觉很奇怪,因为my_complicated_class 可能不应该知道所使用的模板模板参数的任何信息。 (否则,可以声明所有模板模板参数都应该写成可变参数模板,例如template &lt;template &lt;typename...&gt; typename Template&gt;,但这似乎不是模板模板参数通常的写法。)

哪些编译器不符合标准,如何使代码在 C++14 编译器上编译?

【问题讨论】:

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


    【解决方案1】:

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

    相关段落:

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

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

    这是使您的代码在 C++17 中格式良好的最后一句话。当 P 是 template&lt;class&gt; class 而 A 是 template&lt;class...&gt; class 时,P 比 A 更特化。

    【讨论】:

    • 有没有办法在 C++14 编译器上进行类似的工作?
    • @Bernard 有很多工作要做。可接受的内容取决于您准备在代码中更改的内容。你为什么不定义my_complicated_class,就像你在代码注释中所说的那样:template&lt;template&lt;class...&gt;class&gt; class my_complicated_class
    猜你喜欢
    • 1970-01-01
    • 2014-09-08
    • 2014-04-12
    • 2016-12-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2013-09-14
    • 2012-03-28
    相关资源
    最近更新 更多