考虑以下类:
// Class definition
template <template <class...> class... Templates>
class template_pack
{
public:
template <class... Types>
constexpr template_pack(const Types&...) noexcept;
};
// Class template argument deduction guide
template <class... Types>
template_pack(const Types&...) -> template_pack</* something here */>
我们假设 Types...
形式为 template <class...> class... Templates
.我想要的是:
template_pack pack(std::vector<int>{}, std::list<double>{}, std::deque<char>{});
导致:
template_pack<std::vector, std::list, std::deque>;
如何让它发挥作用?
最佳答案
How to make that work?
我看不出有什么办法:总有一些事情是无法推导出来的。
不完全是你问的,但我能想象的最好的通过自定义类型特征传递 ttw
(对于“模板-模板-包装器”)
template <template <typename...> class C>
struct ttw
{
template <typename ... Ts>
constexpr ttw (C<Ts...> const &)
{ }
};
使用隐式推导指南,从构造函数接收的类型中提取模板模板,并将其用作模板参数。
所以你可以写template_pack
使用接收 ttw<Templates>
的构造函数
template <template <typename...> class... Templates>
struct template_pack
{
constexpr template_pack (ttw<Templates> const & ...)
{ }
};
您可以按如下方式使用(同样:通过隐式演绎指南)
template_pack tp1 {ttw{std::vector<int>{}},
ttw{std::set<long>{}},
ttw{std::map<char, short>{}}};
问题是有必要在 ttw{}
中显式包装参数因为,举个例子,std::vector<int>
可转换为 ttw<std::vector>
但不是ttw<std::vector>
.所以,通过 std::vector{}
而不是 ttw{std::vector{}}
,我们遇到了无法推导的常见鸡/蛋问题,因为要推导它,需要进行转换,该转换需要我们要推导的类型知识。
显然,您可以要求显式 ttw
包装适用于特定的 make_template_pack()
功能
template <typename ... Ts>
constexpr auto make_template_pack (Ts && ... ts)
{ return template_pack{ttw{std::forward<Ts>(ts)}...}; }
下面是一个完整的编译示例
#include <map>
#include <set>
#include <vector>
#include <type_traits>
template <template <typename...> class C>
struct ttw
{
template <typename ... Ts>
constexpr ttw (C<Ts...> const &)
{ }
};
template <template <typename...> class... Templates>
struct template_pack
{
constexpr template_pack (ttw<Templates> const & ...)
{ }
};
template <typename ... Ts>
constexpr auto make_template_pack (Ts && ... ts)
{ return template_pack{ttw{std::forward<Ts>(ts)}...}; }
int main ()
{
template_pack tp1 {ttw{std::vector<int>{}},
ttw{std::set<long>{}},
ttw{std::map<char, short>{}}};
auto tp2 { make_template_pack(std::vector<long>{},
std::set<int>{},
std::map<char, short>{}) };
using t0 = template_pack<std::vector, std::set, std::map>;
using t1 = decltype(tp1);
using t2 = decltype(tp2);
static_assert( std::is_same<t0, t1>::value );
static_assert( std::is_same<t0, t2>::value );
}
关于c++ - 从类型中提取模板模板的演绎指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55997142/