如果没有提供 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