gpt4 book ai didi

c++ - 如何使用模板模板参数专门化模板

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:30:51 27 4
gpt4 key购买 nike

最后编辑

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

template <template <typename ...> class P, typename ... Args>
void f(const P<Args...> &p)
{
std::cout << "Template with " << sizeof...(Args) << " parameters!\n";
}

它适用于我目前测试过的任何类型的模板:

f(std::valarray<int>{});    // Prints: "Template with 1 parameters!"
f(std::pair<char, char>{}); // Prints: "Template with 2 parameters!"
f(std::set<float>{}); // Prints: "Template with 3 parameters!"
f(std::map<int, int>{}); // Prints: "Template with 4 parameters!"

但是,假设我想专门化模板,当它采用带有两个参数的模板时,下面的代码不起作用:

template <>
void f<template <typename, typename> class P, typename A, typename B>(const P<A, B> &p)
{
std::cout << "Special case!\n";
}

parse error in template argument list
void f<template <typename, typename> class P, typename A, typename B>(const P<Args...> &p) { std::cout << "Template with " << sizeof...(Args) << " parameters!\n"; }
^
'P' does not name a type
void f<template <typename, typename> class P, typename A, typename B>(const P<Args...> &p) { std::cout << "Template with " << sizeof...(Args) << " parameters!\n"; }
^
expected ',' or '...' before '<' token
void f<template <typename, typename> class P, typename A, typename B>(const P<Args...> &p) { std::cout << "Template with " << sizeof...(Args) << " parameters!\n"; }
^
template-id 'f<<expression error> >' for 'void f(int)' does not match any template declaration
void f<template <typename, typename> class P, typename A, typename B>(const P<Args...> &p) { std::cout << "Template with " << sizeof...(Args) << " parameters!\n"; }

据我所知,使用其他类型的模板参数非常简单:

// Type parameter
template <typename TYPE>
void f(TYPE) { std::cout << "Type!\n"; }

// Non-type parameter
template <int VALUE>
void f() { std::cout << "Value " << VALUE << "!\n"; }

// Type parameter specialization
template <>
void f(float) { std::cout << "Special type case!\n"; }

// Non-type parameter specialization
template <>
void f<666>() { static_assert(false, "Forbidden number!"); }

如何使用 template-template 模板实现此功能?

编辑:

正如 orlp 所指出的和 angew函数模板不能部分特化,所以我应该坚持使用对象模板,here is my attempt :

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)

但是现在,我应该指定所有参数而不是让编译器猜测整个事情,好吧......那不是悲剧。

最佳答案

您正在尝试对您的函数模板进行部分特化——对具有两个模板参数的任何模板进行特化。这在 C++ 中是不允许的。函数模板不能部分特化。

换个角度看:您为模板类型参数和模板非类型参数显示的显式特化使用具体参数。要显式特化您的函数模板,您需要执行以下操作:

template <>
void f<std::pair, int, double>(const std::pair<int, double> &p)
{
std::cout << "Special case!\n";
}

在您的原始代码中,PAB 仍然是“未绑定(bind)的”——它们是参数,而不是实参。显式特化不能有模板参数;被专门化的主模板的所有模板参数必须绑定(bind)到该专门化提供的具体参数。


为了解决您的编辑问题:您仍然可以保留带有参数推导的函数模板接口(interface),并简单地将调用转发给(可能部分专门化的)类模板,如下所示:

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);
}

[Live example]

关于c++ - 如何使用模板模板参数专门化模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29028450/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com