如何避免“模板参数在部分专业化中无法推导”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何避免“模板参数在部分专业化中无法推导”相关的知识,希望对你有一定的参考价值。
我想使用模板访问嵌套类,但无法弄清楚如何操作:示例代码:
template <typename T> class mything {
typedef unsigned key;
T data;
public:
template <typename subT> class mysubthing { typedef subT value_type; };
using subthing = mysubthing<T>;
using subthing_ro = mysubthing<const T>;
};
template<typename T> struct X; // a container for all value_types
#ifdef MAKE_IT_FAIL
// this should automatically set the X<mything<T>::mysubthing<subT>
template<typename T,typename subT> struct X<typename mything<T>::template mysubthing<subT>> {
using value_type = subT;
};
#endif
typedef mything<int> intthing;
#ifndef MAKE_IT_FAIL
template<> struct X<mything<int>::subthing> { using value_type = int; };
template<> struct X<mything<int>::subthing_ro> { using value_type = const int; };
#endif
int main(void) {
intthing t;
X<intthing::subthing>::value_type data = 1; // a data object
X<intthing::subthing_ro>::value_type data_ro = 1; // read-only data object
return 0;
}
这没有-DMAKE_IT_FAIL编译,但当然它完全忽略了模板的要点,因为我想要的是手动输入。如何使用-DMAKE_IT_FAIL使其工作?
答案
你不能像那样专攻:
template<typename T,typename subT>
struct X<typename mything<T>::template mysubthing<subT>> {
因为在C ++中不可能(不支持)从outer<T>::anything_after
这样的类型中推导出T.
在这个一般情况下,你根本不需要专业化。只需定义默认的X,然后只专门化其他情况:
template <typename T> class mything {
typedef unsigned key;
T data;
public:
template <typename subT> struct mysubthing
{
typedef subT value_type;
};
using subthing = mysubthing<T>;
using subthing_ro = mysubthing<const T>;
};
template<typename T> struct X
{
using value_type = typename T::value_type;
};
// this should automatically set the X<mything<T>::mysubthing<subT>
typedef mything<int> intthing;
template<> struct X<mything<int>::subthing> { using value_type = int; };
template<> struct X<mything<int>::subthing_ro> { using value_type = const int; };
int main(void) {
intthing t;
X<intthing::subthing>::value_type data = 1; // a data object
X<intthing::subthing_ro>::value_type data_ro = 1; // read-only data object
return 0;
}
Addendum
根据其中一条评论,X实际上是std::iterator_traits
,已经定义了。在这种情况下,唯一的方法是在mything类之外定义迭代器类:
template <typename T, typename subT>
class mything_iterator {
typedef subT value_type;
};
template <typename T> class mything {
typedef unsigned key;
T data;
public:
using iterator = mything_iterator<T, T>;
using const_iterator = mything_iterator<T, const T>;
};
namespace std {
template<typename T, class subT>
class iterator_traits<mything_iterator<T, subT>>{
using value_type =typename mything_iterator<T, subT>::value_type;
// etc...
};
template<> struct iterator_traits<mything<int>::iterator>
{ using value_type = int; };
template<> struct iterator_traits<mything<int>::const_iterator>
{ using value_type = int; };
}
以上是关于如何避免“模板参数在部分专业化中无法推导”的主要内容,如果未能解决你的问题,请参考以下文章