问题
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)?
回答1:
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.
来源:https://stackoverflow.com/questions/8308213/workaround-for-template-argument-deduction-in-non-deduced-context