非推导上下文的解决方法 [英] Workaround for non-deduced context
问题描述
请考虑以下代码:
#include< iostream>
template< class T>
struct outer {
struct inner {};
};
template< class T>
std :: ostream&运算符<<<<(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; //不编译
}
这不会编译,因为 typename outer< T> :: inner
是一个非保守的上下文(这里),这意味着模板参数类型不能被编译器推导出来(请阅读这个回答为什么)。正如我看到的,我有两个选项可以使它工作:
- 移动
inner
outer
之外,并将其作为类模板。我更喜欢这个,因为对使用代码的影响较小。 - 向inner添加
to_string
>
有没有其他解决方案(在使用代码中不会导致丑陋的语法)?
<你可以将操作符移动到内部类体中,并在它之前放置
friend
。另一种技术是从一个CRTP基础派生内部,该内部参数化由内部(inner)和内部(inner) 。然后使参数类型为CRTP类,并将参数引用转换为派生的 inner
类,其类型由您推导的模板参数给出。 Consider the following code:
#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
}
This does not compile, because typename outer<T>::inner
is a nondeduced context (as explained here), meaning the template-argument-type cannot be deduced by the compiler (read this answer for the why). As I see it, I have two options to make it work:
- Move
inner
outside ofouter
and make it a class-template. I prefer this one, because the impact on the using code is smaller. - Add a
to_string
-method to inner.
Are there any other solutions for this (that do not result in ugly syntax in the using code)?
You can move the operator into the inner class body and put friend
before it. Then replace the parameter type by just inner
.
Another technique is to derive inner from a CRTP base parameterized by inner. Then make the parameter type the CRTP class and cast the parameter reference to the derived inner
class, the type of which is given by the template argument you deduce.
这篇关于非推导上下文的解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!