具有重载 ostream <<运算符的递归类模板

Recursive Class Template with overloaded ostream<< operator

本文关键字:lt 递归 运算符 重载 ostream      更新时间:2023-10-16

我正在尝试实现一个简单的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:usersAdministratordocumentsvisual studio 2013projectscppmaterialsndeptharraysource.cpp(10): warning C4346: 'Array<Type,Dimension>::type' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>          c:usersAdministratordocumentsvisual studio 2013projectscppmaterialsndeptharraysource.cpp(25) : see reference to class template instantiation 'Array<Type,Dimension>' being compiled
1>c:usersAdministratordocumentsvisual studio 2013projectscppmaterialsndeptharraysource.cpp(10): error C2061: syntax error : identifier 'type'
1>c:usersAdministratordocumentsvisual studio 2013projectscppmaterialsndeptharraysource.cpp(10): error C2805: binary 'operator <<' has too few parameters
1>c:usersAdministratordocumentsvisual studio 2013projectscppmaterialsndeptharraysource.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关键字和实际的类参数,但没有任何变化。我们如何为这样的类模板重载运算符?

干杯,Joey

您的方法的问题是无法推断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

然而,在某些上下文中,值不参与类型推导,而是使用模板参数的值在其他地方推导或明确指定。如果模板参数仅在非推导上下文中使用,并且不是显式的指定,模板参数推导失败

附带说明:用模板递归代码为多维数组或向量实现复杂结构是一条不太可维护且肯定很难阅读的路径,只需以不同的步长索引一个连续的内存块,就可以实现更快、更高效(更少的分配)和更清晰的目标。