非推导上下文中模板参数推导的解决方法
考虑以下代码:
#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
是一个非推导上下文(如此处),这意味着编译器无法推导模板参数类型(请阅读这个答案了解原因)。在我看来,我有两个选择来使其工作:
- 将
inner
移到outer
之外,并将其设为类模板。我更喜欢这个,因为对使用代码的影响更小。 - 向内部添加一个
to_string
方法。
是否有其他解决方案(不会导致使用代码中出现丑陋的语法)?
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)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以将运算符移动到内部类主体中,并将
friend
放在它前面。然后将参数类型替换为inner
。另一种技术是从由内部参数化的 CRTP 基础派生内部。然后使参数类型为 CRTP 类,并将参数引用强制转换为派生的
inner
类,该类的类型由您推导的模板参数给出。You can move the operator into the inner class body and put
friend
before it. Then replace the parameter type by justinner
.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.正如我所想,这是非推导上下文的嵌套名称说明符情况,请参阅cppreference。
但这并不意味着您不能显式指定
operator<<
的模板类型。有用:
As I suppose, it is the nested-name-specifier case of the non deduced context, see cppreference.
But it does not mean that you can't specify template types for
operator<<
explicitly.It works: