容器模板包含value_type
类型定义是相当常见的。这使得创建其他模板代码(最近的概念)变得容易,如果只给定Container
而不给定Container<T>
,则能够提取T
。
value_type
,尤其是旧的容器。是否有可能得到包含T
,即使没有它?我知道有一些技巧,比如"如果它是一个迭代器,那么.begin()
应该返回该类型的值",但这并不能帮助我们编写一个概念要求来检查一个类的.begin()
是否确实遵循迭代器的要求。
这里有一个与Quimby的解决方案类似的解决方案,但使用了部分模板特化:
template<typename...>
struct inner_type_impl;
template<template<typename...> typename C, typename T, typename...Args>
struct inner_type_impl<C<T,Args...>>
{
using type = T;
};
template<typename T>
using inner_type = typename inner_type_impl<T>::type;
这是一个借鉴Quimby的解决方案的演示。
可以使用类模板特化或模板参数推导来实现这一点。只要内部类型是第一个模板参数,下面的代码就可以工作:
#include <type_traits>
// Consider the first template argument to be the inner type.
template<template<typename,typename...>class C,typename T,typename...Args>
auto inner_type_impl(const C<T,Args...>* v)->T*{return nullptr;};
template<typename T>
using inner_type = std::remove_pointer_t<decltype(inner_type_impl((T*)nullptr))>;
template<typename T>
struct Container;
// Will still deduce T
template<typename T,typename...Extras>
struct ContainerExtraParams;
static_assert(std::is_same_v<int,inner_type<Container<int>>>);
static_assert(std::is_same_v<int,inner_type<ContainerExtraParams<int,double,float>>>);
我使用指针使代码在求值的上下文中也有效。与std::declval
的可能解决方案相反。