非推导上下文中模板参数推导的解决方法 [英] Workaround for template argument deduction in non-deduced context
问题描述
考虑以下代码:
#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 external< T> :: inner
是非推论上下文(如此处),表示编译器无法推导template-argument-type(请阅读答案(原因)。如我所见,我有两个选择可以使其正常工作:
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:
- 移动
内部
在外部
之外,并使其成为类模板。我更喜欢这一点,因为对使用代码的影响较小。 - 向内部添加
to_string
方法。
- 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)?
推荐答案
您可以将运算符移到内部类主体中,并在其前面放置 friend
。然后,仅用 inner
替换参数类型。
You can move the operator into the inner class body and put friend
before it. Then replace the parameter type by just inner
.
另一种技术是从由inner参数化的CRTP基本派生内部。然后,将参数类型设置为CRTP类,并将参数引用转换为派生的 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屋!