2011-11-29 13 views
12

考虑下面的代码:解决方法nondeduced上下文

#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>::innernondeduced上下文(如所解释here),这意味着该模板参数型不能推导出由编译器(阅读this answer为什么)。在我看来,我有两个选择,使其工作:

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

是否有任何其他的解决方案(这不会导致在使用代码丑陋的语法)?

回答

20

您可以将操作员移动到内部班级主体中,并将​​其放在friend之前。然后用inner替换参数类型。

另一种技术是从内部参数化的CRTP基础派生内部。然后使参数类型为CRTP类,并将参数引用投射到派生的inner类,该类的类型由您推演的模板参数给出。

+1

+1两种技术。希望我能给+2。 – Nawaz

+0

“朋友”方法很好。我不知道你可以在'friend'声明中定义一个函数(对于那些感兴趣的人:我只是查看它,它在2003标准的§11.4.5中定义)。 –