2011-11-29 43 views
12

考慮下面的代碼:解決方法nondeduced上下文

#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 outer<T>::innernondeduced上下文(如所解釋here),這意味着該模板參數型不能推導出由編譯器(閱讀this answer爲什麼)。在我看來,我有兩個選擇,使其工作:

  1. 移動innerouter並使其一類模板。我更喜歡這個,因爲對使用代碼的影響較小。
  2. 添加一個to_string - 內部方法。

是否有任何其他的解決方案(這不會導致在使用代碼醜陋的語法)?

回答

20

您可以將操作員移動到內部班級主體中,並將​​其放在friend之前。然後用inner替換參數類型。

另一種技術是從內部參數化的CRTP基礎派生內部。然後使參數類型爲CRTP類,並將參數引用投射到派生的inner類,該類的類型由您推演的模板參數給出。

+1

+1兩種技術。希望我能給+2。 – Nawaz

+0

「朋友」方法很好。我不知道你可以在'friend'聲明中定義一個函數(對於那些感興趣的人:我只是查看它,它在2003標準的§11.4.5中定義)。 –