【问题标题】:Recursive Class Template with overloaded ostream<< operator具有重载 ostream<< 运算符的递归类模板
【发布时间】:2014-09-28 20:14:28
【问题描述】:

我正在尝试实现一个简单的 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 ==========

我已经尝试了所有的想法,包括删除朋友关键字和实际的类参数,但没有任何改变。我们如何为此类模板重载运算符?

干杯, 乔伊

【问题讨论】:

  • 有什么理由不首先使用std::array

标签: c++ templates


【解决方案1】:

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

然而,在某些情况下,值不参与类型 推论,而是使用模板参数的值 在别处推断或明确指定。如果一个模板 参数仅在非推导上下文中使用,并且未明确使用 指定,模板参数推导失败

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

【讨论】:

  • 知道了。看来我得另谋出路了。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多