c++ - 如何避免 "template parameters not deducible in partial specialization"

标签 c++ c++11 templates nested

我想使用模板访问嵌套类,但不知道该怎么做:示例代码:

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>> {

因为从 outer<T>::anything_after 等类型中推导 T在 C++ 中是不可能的(不支持)。

在这种一般情况下,您实际上根本不需要特化。只需定义默认的 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;
}

附录

根据其中一条评论,X 实际上是 std::iterator_traits , 这已经被定义了。在这种情况下,唯一的解决方法是在神话类之外定义迭代器类:

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; };
}

关于c++ - 如何避免 "template parameters not deducible in partial specialization",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54866659/

相关文章:

c++ - 从 3 个数组中查找最大前 5 个数的优雅代码

c++ - 检查一个类是否可以类型转换为另一个类

c++ - 为什么这段代码用 g++ 编译需要这么长时间?

c++ - C++ 中的列表析构函数

c++ - C++17 引入的评估顺序保证是什么?

c++ - libcudart 和 gcc 的本地构建链接错误的 glibc

c++ - 尝试从元组中删除最后一个类型失败

c++ - 可以将 struct timespec 重用于 nanosleep 吗?

c++ - qobject_cast<QVBoxLayout*>(layout()),是否合适?

c++ - lambda 函数/表达式是否支持 constexpr?