17

考虑以下代码:

#include <iostream>

template<class T>
struct outer {
    struct inner {};
};

template<class T>
std::ostream& operator<<(std::ostream & stream, 
                         typename outer<T>::inner const& value) {
    std::cout << "An outer::inner!";
    return stream;
}

int main() {
    outer<float>::inner foo;

    std::cout << foo << std::endl; // does not compile
}

这不会编译,因为typename outer<T>::inner它是一个非推导上下文(如此所述),这意味着编译器无法推导模板参数类型(请阅读此答案以了解原因)。正如我所看到的,我有两种选择可以让它发挥作用:

  1. 移出并使其成为类模板innerouter我更喜欢这个,因为对使用代码的影响更小。
  2. 将 - 方法添加to_string到内部。

是否有任何其他解决方案(不会导致使用代码中的难看语法)?

4

1 回答 1

23

您可以将运算符移动到内部类主体中并放在friend它之前。然后将参数类型替换为inner.

另一种技术是从由内部参数化的 CRTP 基派生内部。然后将参数类型设为 CRTP 类,并将参数引用强制转换为派生inner类,派生类的类型由您推导出的模板参数给出。

于 2011-11-29T09:12:49.867 回答