我想要做的是能够根据参数的值对同一模板类进行不同的声明,如下所示:
// Enable if X == 2
template <int X, int W, typename Y,
typename A = int, typename B = int> struct Z {};
// Enable if X != 2
template <int X, typename Y,
typename A = int, typename B = int> struct Z {};
我可以从这样的事情开始:
template <int X, int W, typename Y, typename A = int, typename B = int,
typename = std::enable_if_t<X == 2>> struct Z {};
template <int X, typename Y, typename A = int, typename B = int,
typename = std::enable_if_t<X != 2>> struct Z {};
问题在于,可以理解的是,它已经用不同数量的参数重新声明了它。
可变参数模板功能可以派上用场,但不幸的是,它只支持类型而不支持文字,就像在这种情况下一样。
template <typename... Args> struct Z {};
template <int X, int W, typename Y,
typename A = int typename B = int> struct Z<X, W, Y> {};
类型/值不匹配 - &gt;期待一种类型,得到'X / W'
有人有解决方案吗?
修改
很抱歉我之前没有提及,但遗憾的是我无法更改参数的顺序,因为Y
之后的其他参数都有默认值。
答案 0 :(得分:2)
你说你想做的就像你在这里的评论所说:
// Enable if X == 2
template <int X, int W, typename Y, typename A=int, typename B=int>
struct Z {};
// Enable if X != 2
template <int X, typename Y, typename A=int, typename B=int>
struct Z {};
显然,您希望在X !=2
时没有第二个模板参数。您可以在没有名称的情况下定义它。
部分专业化可用于进行选择:
// PRIMARY TEMPLATE: Used if X != 2
template <int X, int, typename Y, typename A=int, typename B=int>
//^^ see here
struct Z {};
// PARTIAL SPECIALIZATION: Used if X == 2
template <int W, typename Y, typename A, typename B>
struct Z<2, W, Y, A, B> {};
编辑1的2: (根据您的评论)
我希望能够仅使用两个参数
(if X!=2)
来使用结构Z:Z<3, int>
您必须重新排序模板并使用主模板中的默认参数
// PRIMARY TEMPLATE: Used if X != 2
template <int X, typename Y, int=0, typename A=int, typename B=int>
//^^ see here
struct Z {};
// PARTIAL SPECIALIZATION: Used if X == 2
template <typename Y, int W, typename A, typename B>
struct Z<2, Y, W> {};
您可以使用as:
Z<2, int> z;
Z<3, int, 5> z3;
编辑2的2: (对您的问题编辑和评论)
用你的话来解释:
我希望能够在不重新排序模板的情况下执行
Z<3, int>
参数
如果第二个模板参数是类型 并且,其他参数为,则您只能执行Z<3, int>
或Z<2, int, ...>
之类的操作拖欠。不幸的是,那不是你的情况。如果这确实是你的问题,那么你在这里走到了尽头。
答案 1 :(得分:1)
如果您可以使用C ++ 14并且您可以接受将您的整数包裹在std::integer_sequence
中,则可以通过这种方式定义Z
的两个版本
#include <iostream>
#include <utility>
template <typename, typename>
struct Z;
template <int W, typename T>
struct Z<std::integer_sequence<int, W>, T>
{ static constexpr int c { 0 }; };
template <int X, typename T>
struct Z<std::integer_sequence<int, 2, X>, T>
{ static constexpr int c { 2 }; };
int main()
{
Z<std::integer_sequence<int, 0>, long> z0;
Z<std::integer_sequence<int, 2, 7>, long> z2;
Z<std::integer_sequence<int, 2>, long> zX; // unacceptable ?
std::cout << "z0: " << z0.c << std::endl; // output: z0: 0
std::cout << "z2: " << z2.c << std::endl; // output: z2: 2
std::cout << "zX: " << zX.c << std::endl; // output: zX: 0
}
我不知道如何将zX
与X == 2
和W
定义为zX
,但如果您希望z2
作为Z
,您可以通过以下方式定义template <typename, typename>
struct Z;
template <typename T, int ... I>
struct Z<std::integer_sequence<int, I ...>, T>
{ static constexpr int c { 0 }; };
template <typename T, int ... I>
struct Z<std::integer_sequence<int, 2, I ...>, T>
{ static constexpr int c { 2 }; };
zX
和2
返回Z
。
第二个解决方案的问题是甚至使用未定义的整数数编译 Z<std::integer_sequence<int, 0, 5, 6, 7>, long> z0;
。我的意思是编译(使用第二个解决方案)
zX
---编辑---
抱歉,我是个白痴。
简单地避免template <typename T>
struct Z<std::integer_sequence<int, 2>, T>;
的定义。
在这两种情况下,您都可以声明(但不定义)以下特化。
item: TG.BaseItem | TG.ClosedItem | any;
答案 2 :(得分:1)
如果不重新排序参数或使用其他数据结构来包装参数,那么您要做的就是不可能。
无论如何,您可以使用json: {"status":"OK"
,"count":1
,"msg_id":"94"
,"when":"2016-08-23 11:21:01"
,"alerts":[
{"msg_id":"44"
,"title":"Medical Emergency"
,"text":"Heart Attack"
,"msg_when":"2016-08-05 14:52:03"
}
]
}
构造函数提交额外参数,并能够在常量表达式中使用您的类型。
举个例子:
constexpr
如果一个好的妥协主要取决于真正的问题。
答案 3 :(得分:0)
如果您可以更改模板参数的顺序,则可以专门化您的类并使用默认值:
// Chosen if X != 2
template<int X, typename Y, typename A = int, typename B = int, int = 0>
struct Z {}; // W is discarded
// Chosen if X == 2
template<typename Y, typename A, typename B, int W>
struct Z<2, Y, A, B, W> {};