Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 涉及模板参数的模板参数解决方法_C++_Templates_Specialization - Fatal编程技术网

C++ 涉及模板参数的模板参数解决方法

C++ 涉及模板参数的模板参数解决方法,c++,templates,specialization,C++,Templates,Specialization,我有以下部分专长: constexpr int NUM_ARGS = 3; template <typename, typename, int> struct Dispatcher; template <typename T, typename V> struct Dispatcher<T, V, NUM_ARGS-1> {}; constexpr int NUM_ARGS=3; 模板结构调度器; 模板 结构调度器{}; 但现在我需要NUM_ARGS本

我有以下部分专长:

constexpr int NUM_ARGS = 3;

template <typename, typename, int> struct Dispatcher;

template <typename T, typename V>
struct Dispatcher<T, V, NUM_ARGS-1> {};
constexpr int NUM_ARGS=3;
模板结构调度器;
模板
结构调度器{};
但现在我需要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...> {};
模板结构测试;
模板
结构测试{};

如果甚至不允许使用默认模板参数?

虽然您不能在专门化参数中对模板参数进行算术运算,但可以在类型参数中进行运算。使用比问题中更简单的示例进行说明:

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;
}
编辑:为了允许可变参数,我们必须保留
专门化
作为类型参数,而不使用默认值,并使用模板别名使接口更干净

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;
}
模板
课堂测试
{
static_assert(std::is_same::value,“不要直接使用Test,而是使用TestHelper”);
公众:

void foo(){请发布一个。你的意思是你需要查看更多的上下文吗?好的,我在我的问题中粘贴了它。乍一看,你的问题似乎是问如何在专门化中使用非类型模板参数进行算术,但你的MCVE没有显示出你实际尝试这样做的迹象-相反,它显示你试图使用一个非常量表达式作为临时变量后期非类型参数。如果您的问题确实是关于后者,请发布一个澄清。我的问题不是关于后者。而是关于如何在专门化中使用非类型模板参数进行算术。因此将NUM_ARGS更改为constexpr并不能解决问题。事实上NUM_ARGS不再是全局的。它是mov我在问题中没有这样做,因为它现在是非法的。好吧,这是一个好的开始。如果
typename Specialization=void
不可能开始,因为有一个模板包,比如说,
template class Test;
,在最后?它必须被删除并且类的重新设计类似于
模板类测试;
,这样就可以将
typename Specialization=void
放在末尾?@prestokeys这是一个有趣的问题-对于函数模板,返回类型是一个可以随时插入SFINAE的地方。我上面的示例中的技巧是在目前,我想不出解决您问题的方法。@prestokeys想不出比使用模板别名模拟默认参数更好的方法了。
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;
}