-1

可能重复:
enable_if 迭代器作为默认模板参数?

我正在寻找在编译时知道是否std::iterator_traits<T>::value_type有效和定义的解决方案。问题在于 std 库将 value_type 的声明转发到 T 中的派生类型:

typedef T::value_type value_type;

我需要在编译时知道 T::value_type 是否是有效类型,以避免与 v​​alue_type 不存在相关的错误。

请考虑以下示例:

std::iterator_traits<int *>::value_type; // OK - should return that value_type exists as it's defined in specialization of std::iterator_traits

std::iterator_traits<const int *>::value_type; // OK - should return that value_type exists as it's defined in specialization of std::iterator_traits

std::iterator_traits<std::vector<int>::const_iterator> >::value_type; // OK - the value_type exists defined within std::vector<int>::const_iterator

std::iterator_traits<int>::value_type; // ERROR - the value_type is not defined within int class - this is what I'm trying to avoid to resolve the value_type of.

我需要该解决方案完全符合 C++ 标准和标准库标准并且独立于编译器。

4

2 回答 2

0

该问题可以通过对此的评论中的方法来显示:

#include <iterator>
#include <iostream>

template <typename T>
class IsIterator {
public:
  struct TrueValue {
  char val;
 };

 struct FalseValue {
   char val[2];
 };

template <typename U>  
 static TrueValue evaluateIsIter(typename U::iterator_category*);

 template <typename U>
 static FalseValue evaluateIsIter(...);

 static const bool value = sizeof(evaluateIsIter<T>(0)) == sizeof(TrueValue);
};


int _tmain(int argc, _TCHAR* argv[])
{
std::cout << IsIterator< int >::value << std::endl;
std::cout << IsIterator< std::iterator_traits<int> >::value << std::endl;
return 0;
 }

VS2005 编译器的结果为:0 1

对此可以看出,这还不足以解决问题。还是我做错了什么?

于 2012-08-14T15:19:11.807 回答
0

解决方案是这样,但缺点是自定义的迭代器类必须在类内部定义 typedef,而不仅仅是专门的 std::iterator_traits 类。

// IsIterator.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <iterator>
#include <iostream>
#include <vector>

template <typename T>
class ExtractType {
public:
  typedef T Result;  
};

template <typename U>
class ExtractType<std::iterator_traits<U> >
{
public:
  typedef U Result;
};

template <typename T>
class IsIteratorPointer
{
public:
  static const bool value = false;
};

template <typename T>
class IsIteratorPointer<T*>
{
public:
  static const bool value = true;
};

template <typename T>
class IsIteratorPointer<const T*>
{
public:
  static const bool value = true;
};

template <typename T>
class IsIterator {
public:
  struct TrueValue {
    char val;
  };

  struct FalseValue {
    char val[2];
  };

  template <typename U>  
  static TrueValue evaluateIsIter(typename U::iterator_category*);

  template <typename U>
  static FalseValue evaluateIsIter(...);

  typedef typename ExtractType<T>::Result TestType;

  static const bool value = IsIteratorPointer<TestType>::value || sizeof(evaluateIsIter<TestType>(0)) == sizeof(TrueValue);
};

struct Foo {  
};

template <> 
struct std::iterator_traits<Foo>
{
  typedef random_access_iterator_tag iterator_category;
};

int _tmain(int argc, _TCHAR* argv[])
{
  std::cout << IsIterator< int >::value << std::endl;
  std::cout << IsIterator< std::iterator_traits<int> >::value << std::endl;
  std::cout << IsIterator< std::iterator_traits<int*> >::value << std::endl;
  std::cout << IsIterator< std::iterator_traits<Foo> >::value << std::endl; // Will be 0 (only drawback) - typedef must be in Foo directly
  std::cout << IsIterator< std::vector<int>::const_iterator >::value << std::endl;

    return 0;
}

现在的问题仍然存在:这个缺点能以某种方式消除吗?

于 2012-08-14T15:45:51.623 回答