C++ 如何使用template tempate参数专门化模板

C++ 如何使用template tempate参数专门化模板,c++,template-specialization,template-templates,C++,Template Specialization,Template Templates,在末尾编辑 我有一个采用模板的函数: template <template <typename ...> class P, typename ... Args> void f(const P<Args...> &p) { std::cout << "Template with " << sizeof...(Args) << " parameters!\n"; } 模板

在末尾编辑

我有一个采用模板的函数:

template <template <typename ...> class P, typename ... Args>
void f(const P<Args...> &p)
{
    std::cout << "Template with " << sizeof...(Args) << " parameters!\n";
}
模板
void f(const P和函数模板不能部分专门化,所以我应该坚持使用对象模板:

模板
结构c
{
使用类型=P;
常数std::size\u t count=sizeof…(Args);
空f(常数类型和t)
{

std::cout好吧,执行您试图执行的操作的正确语法如下:

template <template<typename, typename> class P, typename A, typename B>
void f<P, A, B>(const P<A, B> &p) {
    std::cout << "Special case!\n";
}
模板
无效f(常数P&P){
STD::CUT

你尝试对任何两个模板参数的模板进行函数模板的局部化。C++中不允许这样做。函数模板不能部分地专门化。 从另一个角度看:您为tempalte类型参数和模板非类型参数显示的显式专门化使用具体参数。要显式专门化函数模板,您可以执行以下操作:

template <>
void f<std::pair, int, double>(const std::pair<int, double> &p)
{
    std::cout << "Special case!\n";
}
template <template <typename ...> class P, typename ... Args>
struct c
{
    using type = P<Args...>; 
    static const std::size_t count = sizeof...(Args);

    static void f(const type &t)
    {
        std::cout << "Template with " << sizeof...(Args) << " parameters!\n";
    }
};

template <template <typename, typename> class P, typename A, typename B>
struct c<P, A, B> 
{
    using type = P<A, B>; 

    static void f(const type &t)
    {
        std::cout << "Spezialized 2 parameters!\n";
    }
};

template <template <class ...> class P, class... Args>
void f(const P<Args...> &t)
{
    c<P, Args...>::f(t);
}

你的意思是这样的吗?所以,问题是模板版本是部分专业化,而类型和非类型版本是完全专业化?@PaperBirdMaster非常好。我已经扩展了答案。惊人的@Angew!非常感谢。顺便说一句:coliru链接显示了一个空白页,但我已经测试过了,谢谢。@PaperBirdMaster嗯,这个链接对我很有用。不管怎样,它只是在答案中的代码中添加了4个原始调用(来自你问题中的第2个代码片段)。我对你的修复有问题(请参阅)变量结构与专用结构冲突。@PaperBirdMaster我已经从我的答案中删除了这个示例,但我现在不想写一个工作示例。很抱歉打扰您@orlp,我只是在尝试您的解决方案,抱歉。
template <template <typename ...> class P, typename ... Args>
struct c
{
    using type = P<Args...>; 
    const std::size_t count = sizeof...(Args);

    void f(const type &t)
    {
        std::cout << "Template with " << sizeof...(Args) << " parameters!\n";
    }
};

template <template <typename, typename> class P, typename A, typename B>
struct c<P, A, B> 
{
    using type = P<A, B>; 

    void f(const type &t)
    {
        std::cout << "Spezialized 2 parameters!\n";
    }
};
c<std::valarray, int>                    c_valarray_int;
c<std::pair, int, char>                  c_pair_int_char;
c<std::vector, int, std::allocator<int>> c_vector_int;
c<std::map, int, int>                    c_map_int_int;

c_valarray_int.f({});  // Prints: "Template with 1 parameters!"
c_pair_int_char.f({}); // Prints: "Spezialized with 2 parameters!"
c_vector_int.f({});    // Prints: "Spezialized with 2 parameters!"
c_map_int_int.f({});   // Prints: "Template with 2 parameters!" (expected)
template <template<typename, typename> class P, typename A, typename B>
void f<P, A, B>(const P<A, B> &p) {
    std::cout << "Special case!\n";
}
template <>
void f<std::pair, int, double>(const std::pair<int, double> &p)
{
    std::cout << "Special case!\n";
}
template <template <typename ...> class P, typename ... Args>
struct c
{
    using type = P<Args...>; 
    static const std::size_t count = sizeof...(Args);

    static void f(const type &t)
    {
        std::cout << "Template with " << sizeof...(Args) << " parameters!\n";
    }
};

template <template <typename, typename> class P, typename A, typename B>
struct c<P, A, B> 
{
    using type = P<A, B>; 

    static void f(const type &t)
    {
        std::cout << "Spezialized 2 parameters!\n";
    }
};

template <template <class ...> class P, class... Args>
void f(const P<Args...> &t)
{
    c<P, Args...>::f(t);
}