C++类型特征用于提取模板参数类

11
在一个模板中,我想将模板参数深入到真正的非模板类型中。因此:
template <typename T>
struct MyTemplate
{
    // sadly there's no extract_Base
    typedef typename extract_base<T>::MyType WorkType;
};
struct X {};
template <typename T> struct Templ {};
//MyTemplate<Templ<X>>::WorkType is X;
//MyTemplate<X>::WorkType is X;

我所看到的唯一解决方案是定义真正的基本类型,例如std::vector<X>::value_type为X。但我很好奇是否有一种方法可以在不在每个目标模板中定义辅助类型的情况下实现这一点。
我看到了类似http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html的东西,但这是草案?而且我不太理解它。
是的,我知道有多重继承,但即使对于简单的情况,这也会很好。
更新:Nawaz的解决方案非常适合我,并且很容易扩展到特定的情况,例如:
template<template<typename, typename> class X, typename T1, typename T2>
struct extract_base <X<T1, T2>>   //specialization
{
    typedef T1 base;
};

我甚至可以对T1/T2等应用is_base_of或其他过滤器,所以它适用于X<T,U> - 至少在g++ 4.6.7中是这样的。

这与继承或基类无关。 - Ben Voigt
std::is_base_of,但那可能并不完全适合您的目的。 - dirkgently
1个回答

14

首先,我们将其称为value_type而不是base,因为value_type似乎更适合描述您要提取的类型。

您可以使用以下方法:

template<typename T>
struct extract_value_type //lets call it extract_value_type
{
    typedef T value_type;
};

template<template<typename> class X, typename T>
struct extract_value_type<X<T>>   //specialization
{
    typedef T value_type;
};

只要extract_value_type的模板参数形式为TX<T>,它就能正常工作。但是对于X<T,U>,它将无法工作。不过,在C++11中使用可变模板很容易实现它。
使用方法如下:
template <typename T>
struct MyTemplate
{
    typedef typename extract_value_type<T>::value_type value_type;
};

在线演示:http://ideone.com/mbyvj


现在在C++11中,您可以使用可变模板来使extract_value_type与接受多个模板参数的类模板(例如std::vectorstd::setstd::list等)一起使用。

template<template<typename, typename ...> class X, typename T, typename ...Args>
struct extract_value_type<X<T, Args...>>   //specialization
{
    typedef T value_type;
};

演示: http://ideone.com/SDEgq

@queen3:现在看可变参数解决方案。 - Nawaz
是的,尽管 X<T,U> 对我有用,但请看更新。不过那正是我需要的。 - queen3
嗯,在我的情况下,它是模板X<T>:public T,因此它确实是基础。 - queen3
我需要“typedef typename extract_base<T1>::base base;”进行递归深度基础的旅行...哦天啊。 - queen3
is_base_of 不会有所帮助,因为我根本不知道具体的类型。我只需要任何第一个非模板类型。 - queen3
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接