如何将模板转换为C++11之前的模板

How to transform template to template pre C++11

本文关键字:C++11 转换      更新时间:2023-10-16

受这个问题的触发,我写了一个模板,可以将模板转换为具有不同参数的模板:

template< template <int A,char B,bool> typename T>
struct Add_true {
template <int A,char B> using type = T<A,B,true>;
};

背景:目的是将template<int A, char B, bool C> class A2{};作为模板模板参数传递给template<template<int A, char B> typename T> class A1 {};。我用C++11学习了模板。当我习惯于编写接受类型和"返回"类型的类型/函数,而不是编写接受值和返回值的函数时,我对代码的思考发生了很大的转变。我从未想过,编写一个给定模板"返回"另一个模板的模板也非常简单。问题是,我根本不知道如何在没有别名模板的情况下编写上述或类似内容,这些模板自C++11以来才可用。总是有可能发生的事情如下。给定

template <int A,char B, bool C> struct Foo{};

我可以通过:将布尔参数"绑定"到Foo

template <int A,char B>
struct Add_true_to_Foo {
typedef Foo<A,B> type;
};

但现在Add_true_to_Foo<A,B>::type不是一个模板,如果没有C++11,我根本不知道如何编写一个Add_true,它不仅适用于Foo,也适用于

template <int A,char B, bool C> struct Bar{};

也许我错过了一些显而易见的东西。我的问题是

是否可以在C++11之前编写与上述Add_true等效的程序

没有严格等价的C++11模板使用,但是您可以添加额外的模板类来模仿行为并使用不同的语法:

template <template <int, char, bool> class C>
struct Add_true {
template <int A, char B>
struct apply
{
typedef T<A, B, true> type;
}
};

使用:

template <int A,char B, bool C> struct Foo{};
typedef Add_true<Foo>::apply<42, '*'>::type my_type; // Foo<42, '*', true>

继承将是C++03方式的

template< template <int A,char B,bool> typename T>
struct Add_true {
template <int A,char B>
struct type : T<A,B,true> {};
};

在C++11和C++03中,type都是新模板的名称。区别仅仅在于专业化意味着什么。对于别名模板,它们完全代表被别名化的东西,而在这里它们是新的类型。然而,派生到基的转换应该允许将C++03type特殊化处理得几乎完全像它们是它们"别名"一样。

在C++03中,我们没有模板别名,但使用以下结构模板可以实现相同的别名:

template<template<int A, char B> class T> class A1
{
typedef typename T<1, 'a'>::type actual_A2;
};
template<int A, char B, bool C> class A2 {};
template< template<int A, char B, bool C> class T >
struct Add_true
{
template<int A, char B>
struct apply
{
typedef T<A, B, true> type;
};
};
typedef Add_true<A2> A2_with_true;
A1< A2_with_true::apply > a1;

请注意,您需要更改A1的工作方式,因为它必须使用嵌套的typetypedef才能获得实际的A2专用化。