非推断上下文的解决方法

考虑下面的代码:

#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是一个非导出的上下文 (如这里所解释的),这意味着模板参数types不能被编译器推导出来(阅读这个答案为什么)。 正如我所看到的,我有两个select使其工作:

  1. 移动外部的inner并使其成为类模板。 我更喜欢这个,因为对使用代码的影响较小。
  2. 向内部添加一个to_string方法。

有没有其他的解决scheme(这不会导致在使用代码丑陋的语法)?

您可以将操作员移到内部类体中,然后将其放在friend面前。 然后用innerreplace参数types。

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