2014-07-18 27 views
0

我在滾動我自己的日誌記錄庫。 這個想法是有一個接口類,必須從中派生出來,以便可以從中記錄對象。記錄器庫中POD類型的C++模板專業化

class LoggedType 
{ 
public: 
    virtual std::ostream &log (std::ostream &) const = 0; 
}; 

在這裏,日誌類將實現運營商< <和LoggedType使用日誌方法。對於其他的一切都會正常使用的運營商< <:

typedef std::basic_ostream<char, std::char_traits<char> > CoutType; 
typedef CoutType &(*StandardEndLine)(CoutType&); 

class Log 
{ 
public: 
    Log (std::ostream &); 
    Log (const std::string &); 
    ~Log(); 

private: 
    std::ostream *os; 
    bool file_p; 

    friend Log &operator<< (Log &l, const LoggedType &t) 
    { 
    t.log (*l.os); 
    return l; 
    } 
    template <typename T> 
    friend Log &operator<< (Log &l, const T &t) 
    { 
    *l.os << t; 
    return l; 
    } 
friend Log &operator<< (Log &log, StandardEndLine manip) 
{ 
    manip (*(log.os)); 
    return log; 
} 
}; 

我收到錯誤,LoggedType類也被匹配到模板操作< <,當唯一的非LoggedType類應使用該模板。

如何最好的解決這個問題?

回答

1

你可以改變你的模板函數使用SFINAE:

template <typename T> 
friend 
typename std::enable_if<!std::is_base_of<LoggedType, T>::value, Log &>::type 
operator<< (Log &l, const T &t); 
+0

謝謝,我還沒有收到有關SFINAE想法。然而,它實際上並不工作,因爲GCC仍然抱怨模糊的運算符<< T = const char \ *的重載,其中候選是兩個運算符<<定義。不過,由於const char *不是LoggedType的基礎,所以你建議的那個不應該被認爲是候選者呢? –

+0

Whopps,我在enable_if的條件上犯了一個錯誤。謝謝。 –