如果没有提供 Container::value_type,如何获得 C++ Container<T> 的 T?
How to get at a C++ Container<T>'s T if no Container::value_type is provided?
容器模板包含 value_type
typedef 是很常见的。这使得创建其他模板代码变得容易,最近的概念,如果只给出 Container
而不是 Container<T>
.
,它们能够提取 T
但是,并非所有容器(或其他模板化 classes)都定义了这样的 value_type
,尤其是较旧的容器。
即使没有它,也可以到达包含的 T
吗?
我知道有一些技巧,比如“如果它是一个迭代器,那么 .begin()
应该 return 那个类型的值”,但这对我们没有帮助,例如编写一个概念要求,检查 class 的 .begin()
是否确实符合迭代器的要求。
Class 模板特化或模板参数推导可用于实现这一点。只要内部类型是第一个模板参数,像下面这样的东西就应该起作用:
#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
.
的可能解决方案相反
这是一个类似于 的解决方案,但使用了部分模板专业化:
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 的解决方案中借用的 demo。
容器模板包含 value_type
typedef 是很常见的。这使得创建其他模板代码变得容易,最近的概念,如果只给出 Container
而不是 Container<T>
.
T
但是,并非所有容器(或其他模板化 classes)都定义了这样的 value_type
,尤其是较旧的容器。
即使没有它,也可以到达包含的 T
吗?
我知道有一些技巧,比如“如果它是一个迭代器,那么 .begin()
应该 return 那个类型的值”,但这对我们没有帮助,例如编写一个概念要求,检查 class 的 .begin()
是否确实符合迭代器的要求。
Class 模板特化或模板参数推导可用于实现这一点。只要内部类型是第一个模板参数,像下面这样的东西就应该起作用:
#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
.
这是一个类似于
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 的解决方案中借用的 demo。