Trait typedef在“相同”模板参数的不同上下文中更改

时间:2015-01-15 14:53:38

标签: c++ templates template-specialization typetraits

对于大量的消息来源感到抱歉 - 我认为对于问题的描述我认为是明智的。

我尝试(递归地)提取任何容器的“内容类型”(分别使用特定特征或sfinae特征进行识别)。

我想要达到的目标是content_type<vector<A<int>> == int [如果has_contentcontent_traitA有内容并定义内容类型]。

以下程序发出(MSVC)

content_type<struct A<double> (3627049818)> = double(2699759368)
content_type<struct A<double> (3627049818)> = struct A<double>(3627049818)
0 1 1

这基本上意味着我的特质是在相同类型的不同上下文中提供“不同”(但相同的?!)内容类型。

(注意:std::vector作为含内容类型的标识是通过在原始程序中检查begin / end或subscript [] / size()的特征来提供的。)

#include <iostream>
#include <type_traits>
#include <vector>
#include <typeinfo>
#include <cstddef>

template<class T> struct content_trait;

template<class T> struct has_content : std::false_type {};
template<class T> struct has_content<std::vector<T>> : std::true_type{};

namespace detail
{
  template<class T, bool has_content = content_trait<T>::value>
  struct content_helper { typedef T type; };
  template<class T>
  struct content_helper<T, true>
  { typedef typename content_trait<T>::type type; };
  template<class T>
  struct content_vec_helper
  {
    typedef decltype(*(std::declval<T&>().begin())) value_type;
    typedef typename content_helper<value_type,
      has_content<value_type>::value>::type type;
  };
}

template <class T> struct content_trait
{ typedef typename detail::content_vec_helper<T>::type type; };

template<class T> using content_type 
  = typename detail::content_helper<T, has_content<T>::value>::type;

template<class T> struct A {};
template<class T> struct content_trait<A<T>> { typedef content_type<T> type; };
template<class T> struct has_content<A<T>> : std::true_type { };

template<class T> char const * nameof() { return typeid(T).name(); }
template<class T> std::size_t hashof() { return typeid(T).hash_code(); }
template<class T>
void check()
{
  std::cout << "content_type<" << nameof<T>() << " (" << hashof<T>() << ")";
  std::cout << "> = " << nameof <content_type<T>>();
  std::cout << "(" << hashof<content_type<T>>() << ")";
  std::cout << std::endl;
}

template<class T, class U>
void same()
{
  std::cout << std::is_same<T, U>::value << " ";
  std::cout << (hashof<T>() == hashof<U>()) << " ";
  std::cout << (typeid(T) == typeid(U)) << std::endl;
}

int main()
{
  typedef A<double> a_type;
  typedef detail::content_vec_helper<std::vector<A<double>>>::value_type b_type;
  check<a_type>();
  check<b_type>();
  same<a_type, b_type>();
#ifdef _MSC_VER
  system("pause");
#endif
  return 0;
}

所以......

为什么is_same<A,B>::value0 typeid(A) == typeid(B) && typeid(A).hash_code() == typeid(B).hash_code()? 为什么不是content_type<std::vector<A<double>>> == double

1 个答案:

答案 0 :(得分:2)

目前,你有

detail::content_vec_helper<std::vector<A<double>>>::value_type == A<double>&

来自http://en.cppreference.com/w/cpp/language/typeid

  

1)[..]。如果type是引用类型,则结果引用引用的类型。

在您将TT&进行比较时,typeid 比较是相同的,但类型不同。

您可以将content_vec_helper更改为:

template <class T> struct content_vec_helper
{
    typedef typename std::decay<decltype(*(std::declval<T&>().begin()))>::type value_type;
    typedef typename content_helper<value_type, has_content<value_type>::value>::type type;
};

拥有

detail::content_vec_helper<std::vector<A<double>>>::value_type == A<double>