我有以下部分专业化:
constexpr int NUM_ARGS = 3;
template <typename, typename, int> struct Dispatcher;
template <typename T, typename V>
struct Dispatcher<T, V, NUM_ARGS-1> {};
但是现在我需要NUM_ARGS本身作为Dispatcher中的模板参数。但
template <typename, typename, int, int> struct Dispatcher;
template <typename T, typename V, int NUM_ARGS>
struct Dispatcher<T, V, NUM_ARGS, NUM_ARGS-1> { ...
是非法的。那么解决方法是什么呢?
回应Pradhan的解决方案,这种非法专业化的解决方法是什么?
template <int M, int N, typename... Args> struct Test;
template <int M, typename... Args>
struct Test<M, M-1, Args...> {};
哪里甚至不允许使用默认模板参数?
答案 0 :(得分:1)
虽然您无法对特化参数中的模板参数进行算术运算,但您可以在类型参数中执行此操作。用一个比问题中的例子更简单的例子来说明:
template <int M, int N, typename Specialization = void>
class Test
{
public:
void foo(){cout << "Primary template." << endl;}
};
template <int M, int N>
class Test<M, N, enable_if_t<N==M-1>>
{
public:
void foo(){cout << "Specialization." << endl;}
};
int main()
{
Test<5,10>().foo();
Test<5,4>().foo();
return 0;
}
输出:
Primary template.
Specialization.
编辑:为了允许可变参数,我们必须保留Specialization
作为类型参数而不使用默认值,并使用模板别名来使界面更清晰。
template <int M, int N, typename Specialization, typename... Rest>
class Test
{
static_assert(std::is_same<Specialization, void>::value, "Don't use Test directly. Use TestHelper instead.");
public:
void foo(){cout << "Primary template." << endl;}
};
template <int M, int N, typename... Rest>
class Test<M, N, enable_if_t<N==M-1>, Rest...>
{
public:
void foo(){cout << "Specialization." << endl;}
};
template <int M, int N, typename... Rest>
using TestHelper = Test<M, N, void, Rest...>;
int main()
{
TestHelper<5,10, int, double, char>().foo();
TestHelper<5,4, int, double, char>().foo();
return 0;
}