具有重载ostream的递归类模板<<操作者

时间:2014-09-28 20:14:29

标签: c++ templates

我正在尝试实现一个简单的N维数组。这似乎或多或少正常工作,但我无法让它的重载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 ==========

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

干杯,  乔伊

1 个答案:

答案 0 :(得分: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

  

但在某些情况下,该值不参与类型   推论,但改为使用模板参数的值   要么在别处推断,要么明确指定。如果是模板   参数仅在非推导的上下文中使用,并且不是显式的   指定,模板参数扣除失败

作为旁注:使用模板化递归代码实现多维数组或向量的复杂结构是一种不可维护且难以读取的路径,可以实现更快速完成的任务,更高效(更少的分配)和更清晰,只有一个连续的内存块以不同的步幅索引。

相关问题