2014-09-28 113 views
1

我试图实现一个简单的N维数组。这似乎是或多或少正常工作,但我不能得到它的超载ostream操作工作。这是我目前的执行:带有重载ostream的递归类模板<<运算符

#include <iostream> 
#include <memory> 
#include <vector> 

template <typename Type, int Dimension> 
struct Array { 
    typedef std::vector<typename Array<Type, Dimension - 1>::type> type; 

    template <typename cType, int cDimension> 
    friend std::ostream &operator<<(std::ostream &stream, const Array<cType, cDimension>::type &object) { 
     if (cDimension == 0) { 
      stream << object << ' '; 
     } else { 
      typedef typename Array<cType, cDimension>::type::iterator ArrayIterator; 
      for (ArrayIterator it = object.begin(); it != object.end(); ++it) { 
       typedef typename Array<cType, cDimension - 1>::type NestedArray; 

       NestedArray nArray = (NestedArray)(*it); 
       stream << nArray << std::endl; 
      } 
     } 

     return stream; 
    } 
}; 

template <typename Type> 
struct Array < Type, 0 > { 
    typedef Type type; 
}; 

int main() { 
    Array<int, 1>::type c00 = { 1, 2, 3 }; 
    Array<int, 1>::type c01 = { 2, 3, 4 }; 
    Array<int, 1>::type c02 = { 3, 4, 5 }; 
    Array<int, 2>::type c10 = { c00, c01 }; 
    Array<int, 2>::type c11 = { c01, c02 }; 
    Array<int, 3>::type c20 = { c10, c11 }; 

    std::cout << c20 << std::endl; 

    return 0; 
} 

我得到以下编译错误:

1>------ Build started: Project: NDepthArray, Configuration: Debug Win32 ------ 
1> Source.cpp 
1>c:\users\Administrator\documents\visual studio 2013\projects\cppmaterials\ndeptharray\source.cpp(10): warning C4346: 'Array<Type,Dimension>::type' : dependent name is not a type 
1>   prefix with 'typename' to indicate a type 
1>   c:\users\Administrator\documents\visual studio 2013\projects\cppmaterials\ndeptharray\source.cpp(25) : see reference to class template instantiation 'Array<Type,Dimension>' being compiled 
1>c:\users\Administrator\documents\visual studio 2013\projects\cppmaterials\ndeptharray\source.cpp(10): error C2061: syntax error : identifier 'type' 
1>c:\users\Administrator\documents\visual studio 2013\projects\cppmaterials\ndeptharray\source.cpp(10): error C2805: binary 'operator <<' has too few parameters 
1>c:\users\Administrator\documents\visual studio 2013\projects\cppmaterials\ndeptharray\source.cpp(10): fatal error C1903: unable to recover from previous error(s); stopping compilation 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

我简直想我所有的想法已经,其中包括删除好友关键字和实际的类参数,但没有任何变化。我们如何重载这些类模板的运算符?

干杯, 乔伊

+1

是否有任何理由不首先使用'std :: array'? – 101010 2014-09-28 20:16:10

回答

2

与方法的问题是,cType无法推断:

template <typename Type, int Dimension> // Asking for Type as cType 
struct Array { 
    typedef std::vector<typename Array<Type, Dimension - 1>::type> type; 
} 

template <typename cType, int cDimension>      ↓↓↓↓↓ 
std::ostream &operator<<(std::ostream &stream, typename Array<cType, cDimension>::type &object) 

Array<int, 3>::type c20 = { c10, c11 }; 
std::cout << c20 // Deduction failure 

您可以在这里找到更多的信息:https://stackoverflow.com/a/12566268/1938163

14.8.2.5/4

然而,在某些情况下,第e值不参与 类型的演绎,而是使用 的模板参数的值,这些参数可以在别处推导或明确指定。如果模板 参数仅用于未推导的上下文,并且未明确指定 ,则模板参数推导失败

作为一个旁注:实现多维数组或向量与模板的递归代码复杂的结构是不是非常容易维护和肯定难以读取路径来实现的东西,本来是可以做得更快,更有效的(更少的分配)和更清晰,只有一个连续的内存块在不同的步伐索引。

+0

明白了。似乎我必须找到另一种方式。谢谢您的帮助! – Wrath 2014-09-28 20:46:11