【问题标题】:get decltype of template argument获取模板参数的 decltype
【发布时间】:2014-12-09 15:18:24
【问题描述】:

我经常想要获取类模板参数的 decltype 以便进一步使用它,例如在我已经剥离和简化以显示我的问题的循环中:

template <typename T>
class Foo {
public:
    T type; //This is my hack to get decltype of T
};

template <typename T>
class Bar {
public:

};

int main() {
    for(auto& foo : fs) {
        //Is there some way to get the decltype of the template without having to refer to some arbitrary T member of Foo?
        auto bar = someFunction<decltype(foo.type)>();
    }
}

有没有办法在不做这个 hack 的情况下获取模板参数的 decltype ?如果不是,那么获取此类值的 decltype 的最佳解决方法是什么?

【问题讨论】:

  • 它只是一个包含这些对象的向量,抱歉可以省略(或解释它)。关键是我使用 auto 是因为我实际上遍历了一个元组,然后遍历了向量 (fs),这就是为什么我真的想使用 auto 然后从中提取模板类型。
  • 这个细节很关键。向量是同质的。

标签: c++ templates decltype


【解决方案1】:

你可以创建一个 type_traits:

template <typename C>
struct get_template_type;

template <template <typename > class C, typename T>
struct get_template_type<C<T>>
{
    using type = T;
};

然后你使用它(假设C = Foo&lt;T&gt;,你将拥有T

typename get_template_type<C>::type

Live example

编辑:对于具有多个模板参数的类,检索第一个:

template <template <typename > class C, typename T, typename ... Ts>
struct get_template_type<C<T, Ts...>>
{
    using type = T;
};

【讨论】:

  • 谢谢,这是我需要的!
  • 这不适用于具有默认参数的模板或具有多个参数的模板,例如std::vector
  • 您能否添加一个示例,说明如何在我的场景中使用它?我以为我有,但我没有。
  • 非常好,谢谢。如果你能放纵我,最后一件事;有没有办法让它更短,我可以创建一个返回 typedef 或其他东西的函数吗?
  • @Gerard:为了避免typename ..::type,您可以添加别名template &lt;typename T&gt; using get_template_type_t = typename get_template_type&lt;T&gt;::typedecay_t 相同(应该存在于 C+++14 中))。要完全删除 decay,您可以添加专业化,例如 template &lt;typename T&gt; struct get_template_type&lt;const T&amp;&gt; : get_template_type&lt;T&gt; {};
【解决方案2】:

标准库中的所有内容都只有类本地类型定义:

template<typename T>
struct Bla
{ using value_type = T; }

所以你可以这样做:

template<typename T>
void f(const T& t)
{
  typename T::value_type some_var_with_template_type;
}

或者,您可以修改调用函数:

template<template<typename> class Class, typename T>
void f(const Class<T>& c)
{
  T some_var_with_template_type;
}

但这会对可用性和通用性施加限制。因为例如,如果 Class 有多个模板参数,这将失败(尽管可以使用可变参数模板来解决此问题)。可变参数模板版本:

template<template<typename, typename...> class Class, typename T, typename... ArgTypes>
void f(const Class<T, ArgTypes...>& t)
{
  T some_var_of_template_type;
}

注意value_type typedef 是迄今为止最干净和最惯用的解决方案。

Some code to show how the functions would need to be written and used.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 2017-04-11
    • 1970-01-01
    • 2022-06-23
    相关资源
    最近更新 更多