2016-09-10 41 views
1

我正在写一些笔记,并且为了编译起见,我为ostream添加了operator<<重载函数,作为template。它编译得很好,但是,由于我把class type中的class type重载到template<>中,并将该类型作为重载函数的第二个输入传递,是不是将它从现在开始用于EVERY类的新运算符? 这是我的代码以供参考。 它纯粹是为了便于说明,它没有功能。当我将运算符重载为模板时会发生什么?

template <class type> 
ostream& operator<< (ostream& s, type x){ 
    s << x.getsmth(); 
    //... 
} 
+0

*“不会用它为每一个类,我从现在开始定义新的运营商? “*是的,基本上。这就是为什么添加这样的模板超载是不明智的。 –

+0

当然,如果没有找到那里调用的方法,编译器会抱怨疯狂。我也这么想。 –

+0

不适用于每个类,只适用于那些没有其他重载更好(例如,特定于类)并且与您定义的模板位于同一名称空间中(由于[ADL](http:// en .cppreference.com/w/cpp/language/adl)规则)。 –

回答

0

我为自己是新手,当谈到SFINAE,但好像你是正确的,这个模板将被用于不提供getsmth()类,即使身体不编译。您可以防止这种虽与SFINAE发生的事情,这似乎按预期方式工作:

template <class T, typename = decltype(T().getSomething())> 
std::ostream& operator<< (std::ostream& s, T& x){ 
    s << x.getSomething(); 
    return s; 
} 

演示:http://cpp.sh/8fyk

+0

是的,你可以这样做,但有什么意义?如果你只是在课堂上定义它,它会为你节省麻烦。 我想你可以做另一件事。在任何类的外部定义方法,然后添加“friend”,然后添加所需类的第一行。尽管这只适用于具有子类的类。 –

+0

这个例子正在处理任何在其中定义了成员函数'getSomething'的类。它将与来自外部代码的类一起工作,并且不会将特定层次结构中的类绑定在一起。如果你想在任何一个类中添加一个函数print,并使这个函数有效,它也可能会有用。 –