请教关于类模板的局部特化

时间:2022-08-24 20:51:30
问题描述:写了个小例子,想得到容器中(比如stack)元素的类型,代码如下:
template <typename T>
class ElementT
{
//public:
//    typedef T Type;
};

//局部特化
template <typename T, template <typename> class P>
class ElementT<P<T>>
{
public:
    typedef T Type;
};

//输出容器中元素的类型
template <typename T>
void print_element_type(T const& c)
{
cout << "Container of "
<< typeid(typename ElementT<T>::Type).name()
<< " elements"
<< endl;
}

int main()
{
stack<bool> s;
print_element_type(s);
return 1; 
}


编译不通过,错误如下:
error C2039: 'Type' : is not a member of 'ElementT<T>'

class ElementT
{
//public:
//    typedef T Type;
};

的注释去掉,通过编译,可是输出结果为S的类型,并不是想得到的元素"bool"的类型。
分析原因是在实例化的时候没有用局部特化“ElementT<P<T>>”,
但是用stack<bool>去匹配P<T>不是很合适吗?难道是在特化中不能有模板的模板参数?

在线请教中,谢谢

11 个解决方案

#1


template <typename T, template <typename> class P>看来偶模板没学好啊,这种特化实在看不懂

#2




#include <iostream>
#include <algorithm>
#include <functional>
#include <stack>
#include <list>
#include <vector>
using namespace std;

template <typename T>
class ElementT
{
   public:
       typedef typename T::value_type Type;
};


//输出容器中元素的类型
template <typename T>
void print_element_type(T const& c)
{
    cout << "Container of "
        << typeid(typename ElementT<T>::Type).name()
        << " elements"
        << endl;
}


int main()
{
    stack<bool> s;
    print_element_type(s);

    list<int> l;
    print_element_type(l);

    vector<double> v;
    print_element_type(v);

    return 1; 
}

-------------

Container of bool elements
Container of int elements
Container of double elements
请按任意键继续. . .




#3


谢谢楼上的强人帮我实现功能,能否继续赐教为什么在我的那段代码中stack <bool>不能匹配P <T>,谢谢。

#4


因为模板是在实例化的时候才检查类型的问题,你的stack或许就没有type这个类型,因此,你要在你使用的传入模板里面定义这么一个东西:

输出:

Container of class std::stack<bool,class std::deque<bool,class std::allocator<bool> > > elements


完整代码:
#include <stack>
#include <iostream>
#include <typeinfo.h>

using namespace std;

template <typename T>
class ElementT
{
public:
    typedef T Type;
};

//局部特化
template <typename T, template <typename> class P>
class ElementT<P<T>>
{
public:
typedef typename T::Type Type;
};

//输出容器中元素的类型
template <typename T>
void print_element_type(T const& c)
{
    cout << "Container of "
        << typeid(typename ElementT<T>::Type).name()
        << " elements"
        << endl;
}

int main()
{
    stack<bool> s;
    print_element_type(s);
    return 1; 
}

#5


谢谢楼上的提示,我知道原因了,模板的模板参数不能直接调用缺省的模板参数。
因为stack的声明是:

template<class _Ty,
class _Container = deque<_Ty> >
class stack

所以“Container ”要显式的指定,将特化改为下面的代码就搞定了:


//局部特化
template <typename T, template <typename T1, typename = deque<T1>> class P>
class ElementT<P<T>>
{
public:
    typedef T Type;
};

再次感谢大家的帮助,小弟结贴

#6


stack的实际类型是
class std::stack<bool,class std::deque<bool,class std::allocator<bool> > >

并不是 简单的 P<T> 

#7


stl的每个容器内部都保存了元素类型 value_type

直接这样就ok了



template<typename T>
void print_element_type(const T& t)
{
    cout << "Container of "
        << typeid(T::value_type).name()
        << " elements"
        << endl;
}

#8


:) 

#9


ps : steedhorse 老大最近不知道在忙什么呢 >_<

#10


呵呵,楼上是哦模板高手啊,以后一定要多请教了

#11


:D

#1


template <typename T, template <typename> class P>看来偶模板没学好啊,这种特化实在看不懂

#2




#include <iostream>
#include <algorithm>
#include <functional>
#include <stack>
#include <list>
#include <vector>
using namespace std;

template <typename T>
class ElementT
{
   public:
       typedef typename T::value_type Type;
};


//输出容器中元素的类型
template <typename T>
void print_element_type(T const& c)
{
    cout << "Container of "
        << typeid(typename ElementT<T>::Type).name()
        << " elements"
        << endl;
}


int main()
{
    stack<bool> s;
    print_element_type(s);

    list<int> l;
    print_element_type(l);

    vector<double> v;
    print_element_type(v);

    return 1; 
}

-------------

Container of bool elements
Container of int elements
Container of double elements
请按任意键继续. . .




#3


谢谢楼上的强人帮我实现功能,能否继续赐教为什么在我的那段代码中stack <bool>不能匹配P <T>,谢谢。

#4


因为模板是在实例化的时候才检查类型的问题,你的stack或许就没有type这个类型,因此,你要在你使用的传入模板里面定义这么一个东西:

输出:

Container of class std::stack<bool,class std::deque<bool,class std::allocator<bool> > > elements


完整代码:
#include <stack>
#include <iostream>
#include <typeinfo.h>

using namespace std;

template <typename T>
class ElementT
{
public:
    typedef T Type;
};

//局部特化
template <typename T, template <typename> class P>
class ElementT<P<T>>
{
public:
typedef typename T::Type Type;
};

//输出容器中元素的类型
template <typename T>
void print_element_type(T const& c)
{
    cout << "Container of "
        << typeid(typename ElementT<T>::Type).name()
        << " elements"
        << endl;
}

int main()
{
    stack<bool> s;
    print_element_type(s);
    return 1; 
}

#5


谢谢楼上的提示,我知道原因了,模板的模板参数不能直接调用缺省的模板参数。
因为stack的声明是:

template<class _Ty,
class _Container = deque<_Ty> >
class stack

所以“Container ”要显式的指定,将特化改为下面的代码就搞定了:


//局部特化
template <typename T, template <typename T1, typename = deque<T1>> class P>
class ElementT<P<T>>
{
public:
    typedef T Type;
};

再次感谢大家的帮助,小弟结贴

#6


stack的实际类型是
class std::stack<bool,class std::deque<bool,class std::allocator<bool> > >

并不是 简单的 P<T> 

#7


stl的每个容器内部都保存了元素类型 value_type

直接这样就ok了



template<typename T>
void print_element_type(const T& t)
{
    cout << "Container of "
        << typeid(T::value_type).name()
        << " elements"
        << endl;
}

#8


:) 

#9


ps : steedhorse 老大最近不知道在忙什么呢 >_<

#10


呵呵,楼上是哦模板高手啊,以后一定要多请教了

#11


:D