这个编译和工作应该(非嵌套模板):
#include <iostream>
template<typename T> class Z;
template <typename T> 
std::ostream& operator<< (std::ostream& os, const Z<T>&) {
    return (os << "Z");
}
template<typename T> class Z {
    friend std::ostream& operator<< <> (std::ostream& os, const Z&);
};
int main () {
    Z<int> z;
    std::cout << z << std::endl;
}
这个不编译(gcc 4.4和gcc 4.6,在03和0x模式下):
#include <iostream>
template<typename T> class Z;
template<typename T> 
std::ostream& operator<< (std::ostream& os, const typename Z<T>::ZZ&) {
    return (os << "ZZ!");
}
template <typename T> class Z {
  public:
    class ZZ {
        friend std::ostream& operator<< <> (std::ostream& os, const ZZ&);
    };
};
int main () {
    Z<int>::ZZ zz;
    std::cout << zz << std::endl;
}
错误消息如下所示:
error: template-id ‘operator<< <>’ for ‘std::ostream& operator<<(std::ostream&,
const Z<int>::ZZ&)’ does not match any template declaration
error: no match for ‘operator<<’ in ‘std::cout << zz’
在0x模式下,第二条错误消息不同,但含义相同.
有可能做我想做的事吗?
编辑显然,这里有一个非推断上下文的实例,它解释了错误消息.然而,问题仍然存在:我可以operator<<为嵌套在类模板中的类工作吗?
这是功能的一般问题:
template <typename C>
void func(typename C::iterator i);
现在,如果我打电话func(int*),C我应该使用哪个值?
一般来说,你不能倒退!许多不同的人C可能已经定义了一个内部类型iterator,恰好是int*某些参数集.
在你的情况下,你有点复杂的情况:
template <typename T>
void func(typename Z<T>::ZZ const&);
但从根本上说这是同一个问题,Z<T>是一个模板,而不是一个完整的类,你要求为ZZ这个模板的内部类型创建一个函数.
假设我这样做:
template <typename T>
struct Z { typedef T ZZ; };
template <typename T>
struct Z<T const> { typedef T ZZ; };
注意:典型的迭代器,value_type不是const限定的
然后,在调用时func(int),我应该使用Z<int>或Z<int const>?
这是不可扣除的.
因此,整个事物被称为不可推导的背景,标准禁止它,因为没有明智的答案.
经验法则:typename对函数的参数持怀疑态度.
注意:如果另一个参数已经固定了类型,它们就可以了,例如typename C::iterator find(C&, typename C::const_reference);因为一旦C推断出来,那么C::const_reference可以毫无困难地使用它们
马蒂厄很好地解释了这个问题,但在这种情况下可以使用一个简单的解决方法。您可以使用友元声明在类中实现友元函数:
#include <iostream>
template <typename T> class Z {
public:
  class ZZ {
    friend std::ostream& operator<< (std::ostream& os, const ZZ&) {
      return os << "ZZ!";
    }
  };
};
int main () {
  Z<int>::ZZ zz;
  std::cout << zz << std::endl;
}
| 归档时间: | 
 | 
| 查看次数: | 1904 次 | 
| 最近记录: |