所以我对这样的代码有疑问:
我有这样的结构
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
或bool
的“ Inner<int N>
”结构,并将Outer::val
设置为Inner::val
或bool
所以我创建了这样的东西(不起作用):
template <bool B>
struct Outer
{
enum
{
val = B
};
};
template <Inner<int> I>
struct Outer
{
enum
{
val = I::val
};
};
这有什么问题,以及如何解决? (我见过类似的问题,但仍然无法将其应用于我的问题)
答案 0 :(得分:2)
您的代码中存在一些问题。
首先:您定义两个不同的Outer
结构
template <bool B>
struct Outer
{ /* ... */ };
template <Inner<int> I>
struct Outer
{ /* ... */ };
你不能。
如果需要,可以声明一个Outer
结构和两个专业化,但是必须确定必须接收哪种类型的模板参数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;
答案 1 :(得分:2)
模板参数可以是类型,值(非类型)或模板[temp.param]。您要实现的目标要求模板 substring 012345 0
012345
substring 012345 1
12345
substring 012345 2
2345
substring 012345 3
345
substring 012345 4
45
substring 012345 5
5
substring 012345 6
substring 012345 3 5
345
substring 012345 3 4
34
substring 012345 2 4
234
substring 012345 1 3
123
具有一个可以是类型或值的参数。不幸的是,这是不可能的。
您可以做的是将bool值包装为以下类型:
Outer
,然后为template <bool b>
struct InnerBoolean
{
static constexpr bool val = b;
};
Outer
,然后使用template <typename T>
struct Outer
{
enum
{
value = T::val
};
};
和Outer<Inner<4>>
。
如果您将Outer<InnerBoolean<False>>
重命名为val
,则无需编写自己的包装器,而是可以使用标准库在std::bool_constant
和value
和{{ 1}}。
在C ++ 17之前的版本中,非类型模板参数不能为类类型[temp.param]/4,而C ++ 20将取消此限制,并允许任何literal type模板参数。因此,只要std::true_type
可以是文字类型,您就可以直接传递类型为std::false_type
的值并使用自动模板参数:
Inner