首页 > 解决方案 > C++ 嵌套模板结构

问题描述

所以我对这样的代码有问题:

我有这样的结构

template <int N>
struct Inner
{
    enum
    {
        val = 2*N
    };
};

我想达到这样的目标:

int v = Outer<Inner<4>>::val;
int b = Outer<false>::val;
cout<< v <<endl;
cout<< b <<endl;

我的目标是创建“ Outer”结构,它采用boolorInner<int N> 并设置Outer::valInner::valorbool 所以我创建了这样的东西(不工作):

template <bool B>
struct Outer
{
    enum
    {
        val = B
    };
};

template <Inner<int> I>
struct Outer
{
    enum
    {
        val = I::val
    };
};

这有什么问题以及如何解决?(我见过一些类似的问题,但仍然无法将其应用于我的问题)

标签: c++templatesmetaprogrammingtemplate-meta-programmingtemplate-specialization

解决方案


您的代码中存在一些问题。

首先:你定义了两个不同的Outer结构

template <bool B>
struct Outer
 { /* ... */ };

template <Inner<int> I>
struct Outer
 { /* ... */ };

而你不能。

如果需要,您可以声明一个Outerstruct 和两个specializations,但您必须决定Outer必须接收哪种类型的模板参数。

因为,看着你的渴望,

int v = Outer<Inner<4>>::val;
int b = Outer<false>::val;

您想在一种情况下传递一个类型 ( Inner<4>),在另一种情况下传递一个值。而你不能。

您必须决定是否Outer接收类型或值。在 C++17 之前,如果接收一个值,则必须确定该值的类型;从 C++17 开始,您可以声明Outer为接收泛型类型auto的值(作为值的类型)。

问题:Inner<int>不能是模板参数的值(但另请参阅 Michael Kenzel 的回答,它显示了基于模板值参数的可能的 C++20 解决方案)。

所以我看到的唯一解决方案(在 C++20 之前)是声明Outer为接收类型

template <typename>
struct Outer;

然后你可以为类型定义一个Outer专业化Inner

template <int N>
struct Outer<Inner<N>>
 { enum { val = Inner<N>::val }; }; // or simply enum { val = N };

对于bool值,您必须将它们包装在一个类中;我建议(从 C++11 开始)使用标准类std::integral_constant和定义以下Outer特化

template <bool B>
struct Outer<std::integral_constant<bool, B>>
 { enum { val = B }; };

使用方法如下

int v = Outer<Inner<4>>::val;
int b = Outer<std::integral_constant<bool, false>>::val;

std::cout << v << std::endl;
std::cout << b << std::endl;

您还可以使用std::false_type定义b

int b = Outer<std::false_type>::val;

并且,从 C++17 开始,还有std::bool_constant(值的std::integral_constant简写bool

int b = Outer<std::bool_constant<false>>::val;

推荐阅读