请考虑以下代码:
#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
是非弱化上下文(如here所述),这意味着编译器无法推断出模板参数类型(读取) this answer为什么)。在我看来,我有两个选项可以让它发挥作用:
inner
移到outer
之外,并将其设为类模板。我更喜欢这个,因为对使用代码的影响较小。to_string
- 方法。是否还有其他解决方案(在使用代码中不会导致语法难看)?
答案 0 :(得分:22)
您可以将运算符移动到内部类主体中,并将friend
放在其前面。然后只用inner
替换参数类型。
另一种技术是从内部参数化的CRTP基础派生内部。然后使参数键入CRTP类并将参数引用强制转换为派生的inner
类,其类型由您推导的模板参数给出。